You have created a new Hash
with an Array
as an accumulator when the key is not present so
hash = Hash.new([])
hash[:one] << "uno"
hash[:one] == ["uno"] #=> true
but
hash[:two] << "dos"
(hash[:one] == hash[:two]) && (hash[:two] == ["uno","dos"]) #=> true
hash[:three] == ["uno","dos"] #=> true
because ["uno","dos"]
is the original array created with the Hash
and hash[:non_existant_key]
points to it.
Note: no keys have actually been added to hash
in this case. It would be similar to
a = []
hash = {}
hash.fetch(:one,a) << 'uno'
hash.fetch(:two,a) << 'dos'
hash.fetch(:three, a)
#=> ['uno','dos']
hash
#=> {}
To solve this you can use this syntax as mentioned in your second test
hash = Hash.new {|h,k| h[k] = [] }
This means fro every new key instantiate a new Array
as its value rather than reusing the same Array
over and over again
This is the problem with the Hash.new(obj)
syntax when obj
is a mutable object