From: "Jesús Gabriel y Galán" Date: 2011-11-18T02:52:47+09:00 Subject: Re: Problem on hash with default value On Thu, Nov 17, 2011 at 6:45 PM, Florent G. wrote: > 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. 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.