Problem on hash with default value

Hi,

I face the following issue with a hash having an empty array as default
value.

I don’t how to describe it in English, here is an illustrative code:

hash = Hash.new Array.new

hash[:a] = [1]

hash[:b] << 2

puts hash[:b]

=> returns [2]

puts hash.keys

=> returns [:a], not [:a, :b] ?

hash[:b] is set to [2] but I don’t understand why hash.keys does not
include :b.

Thanks!,
Florent

On Thu, Nov 17, 2011 at 6:45 PM, Florent G. [email protected] wrote:

hash[:b] << 2

puts hash[:b]

=> returns [2]

puts hash.keys

=> returns [:a], not [:a, :b] ?

hash[:b] is set to [2] but I don’t understand why hash.keys does not
include :b.

The reason is that the Hash constructor you are using uses the object
you pass, in your case, Array.new, to return when you access a
non-existing key. But, it doesn’t assign the array to the key. You
have to do it yourself. One way is to use the default proc:

h = Hash.new {|hash, k| hash[k] = Array.new}

This will create a new array and assign it to a key, whenever you
access a non-existing key:

ruby-1.8.7-p334 :001 > h = Hash.new {|hash, k| hash[k] = Array.new}
=> {}
ruby-1.8.7-p334 :002 > h[:a]
=> []
ruby-1.8.7-p334 :003 > h
=> {:a=>[]}

Also, keep in mind that the other constructor you were using will
return the same Array instance to all non-existing keys:

ruby-1.8.7-p334 :004 > h = Hash.new Array.new
=> {}
ruby-1.8.7-p334 :005 > h[:a]
=> []
ruby-1.8.7-p334 :006 > h[:a] << 2
=> [2]
ruby-1.8.7-p334 :007 > h[:a]
=> [2]
ruby-1.8.7-p334 :008 > h[:b]
=> [2]

Jesus.

Go ahead and check the doc:

http://www.ruby-doc.org/core-1.9.3/Hash.html#method-c-new

maybe its interessing for you:
an Hash wich used an default_proc
is not mashalble anymore, so you can not dump it

Make sense, thanks!

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs