In Python, I can make a hash where each element has a default value when it's first referenced (also know as "autovivification"). Here's an example:
from collections import defaultdict
d = defaultdict(int)
d["new_key"] += 1
print d
Printing the dict shows the value for "new_key" is 1.
What's the equivalent in Ruby? This code throws an error:
d = {}
d[:new_key] += 1
puts d
test.rb:3:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
You can use the first argument of the Hash.new
method for that:
d = Hash.new 0
d[:new_key] += 1
d[:new_key] #=> 1
d[:foo] #=> 0
Be careful - you might accidentally change the default value:
h = Hash.new("Go Fish")
h[:unknown_key] #=> "Go Fish"
h[:unknown_key].upcase! #=> "GO FISH"
h[:next_key] #=> "GO FISH"
As "mu is too short" pointed out in his answer, you should better use a proc, as in:
h = Hash.new { |h, k| h[k] = 0 }