Hash's default value doesn't work like you're expecting it to. When you say h[k]
, the process goes like this:
- If we have a
k
key, return its value.
- If we have a default value for the Hash, return that default value.
- If we have a block for providing default values, execute the block and return its return value.
Note that (2) and (3) say nothing at all about inserting k
into the Hash. The default value essentially turns h[k]
into this:
h.has_key?(k) ? h[k] : the_default_value
So simply accessing a non-existant key and getting the default value back won't add the missing key to the Hash.
Furthermore, anything of the form:
Hash.new([ ... ])
# or
Hash.new({ ... })
is almost always a mistake as you'll be sharing exactly the same default Array or Hash for for all default values. For example, if you do this:
h = Hash.new(['a'])
h[:k].push('b')
Then h[:i]
, h[:j]
, ... will all return ['a', 'b']
and that's rarely what you want.
I think you're looking for the block form of the default value:
h = Hash.new { |h, k| h[k] = [ 'alright' ] }
That will do two things:
- Accessing a non-existent key will add that key to the Hash and it will have the provided Array as its value.
- All of the default values will be distinct objects so altering one will not alter the rest.