Hash default value

Comments

The other day while working on a problem on exercism.io I was wanting to keep a hash of arrays, and I wanted each key in the hash to default to a empty array. So I started with

1
hash = Hash.new([])

I then procedded to be able to append to the array for each key, so I tried:

1
hash[key] << "value"

I was expecting this to append to the empty array and set the key to:

1
["value"]

Unfortunately this is not the case. What actually happens is I am changing the default value for the hash like so:

1
2
3
4
5
hash = Hash.new([])
p hash[2] # => []
hash[1] << "value"
p hash #  => {}
p hash[2] # => ["value"]

The problem is that it is returning a reference to the default array and then modifying it in place. So how do you fix this? You need to use the block syntax for the default hash value.

1
2
3
4
hash = Hash.new {|hash, key| hash[key] = []}
hash[1] << "value"
p hash # => { 1 => ["value"] }
p hash[2] # => []

If you want to look at it another way you can try:

1
2
3
4
5
6
7
hash = Hash.new([])
hash[1].object_id # => 70252744684240
hash[2].obhect_id # => 70252744684240

hash = Hash.new{|h,k| h[k] = []}
hash[1].obejct_id # => 12321412312
hash[2].obejct_id # => 41241442143

So with the first way, you get returned the same object every time. But with the block syntax you a new

Comments