Ruby 101: Hash initialization gotcha

I have a code that counts how many times a word occurs – a perfect fit for Hash.

  def word_counts(words)
    counts = Hash.new(0)
    words.each do |word|
      counts[word] += 1
    end
  end
  
  categories = {
    :a => word_counts(‘some text’)
    :b => word_counts(‘another set of text’)
  }

Somewhere, I use the hash returned by the word_counts method to do some calculation.

  def score(word_scores, words)
    words.each do |word|
      v = word_scores[word]
      v = 0.1 if v.nil?
  
      score += Math.log( v / some_value )
    end
  end
  
  categories.each do |category, word_counts|
    score(word_counts, %w{some random text})
  end

When I run the score, I always get an ‘Infinity’. After some debugging, the problem is this piece of code:

  v = word_scores[word]
  v = 0.1 if v.nil?

‘word_scores’ returns 0 if ‘word’ doesn’t exist; not nil which is the default behavior. Later, I realized I initialized it via Hash.new(0) which makes 0 the default value. In fact, it is not even necessary to check for nil or 0. All we want is to retrieve the value referenced by the key, and if the key does not exist, give me 0.1.

  v = word_counts.fetch word, 0.1
About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s