Consider this code:
h=Hash.new(0) #new hash pairs will by default have 0 as values
h[1]+=1 # {1=>1}
h[2]+=2 # {2=>2}
that's all fine, but:
h=Hash.new([]) #empty array as default value
h[1]<<=1 #{1=>[1]} - OK
h[2]<<=2 #{1=>[1,2], 2=>[1,2]} # why ??
At this point I expect the hash to be:
{1=>[1], 2=>[2]}
But something goes wrong.
Does anybody know what happens?
When you call Hash.new([])
,
the default value for any key is not just an empty array, it's the same empty
array.
To create a new array for each default value, use the block form of the constructor:
Hash.new { [] }
You're specifying that the default value for the hash is a reference to that particular (initially empty) array.
I think you want:
h = Hash.new { |hash, key| hash[key] = []; }
h[1]<<=1
h[2]<<=2
That sets the default value for each key to a new array.