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
Advertisement
Leave a Comment