Gavin Sinclair wrote:

> From: "John Tromp" <tromp / serpens.ins.cwi.nl>
>> [all code snipped]
>> but unfortunately, the default value [] for the Hash is shared by all
>> elements, rather than copied, as I expected.
>>
>> I was wondering if this was a conscious design decision, or an oversight.
>> I finally ended up with the much uglier
>>
>> Is there another way to avoid the explicit tests?
> 
> 
> It's a common problem (are you listening, Bill :).
> 
> I don't know about the design decision, but can offer a nicer solution. 
> Others will undoubtably have others; I remember there being some clever
> ones expressed in the past, but not what they are :(
> 
> Anyway:
> 
>   (hash[key] ||= []) << value
> 
> Make sense?
> 
> Gavin

This seems similar to the problem with Array.new:

Array.new(5, []) will put the same "[]" in each cell, so:

a = Array.new(5, [])
a[2] << 3
a  # [[3],[3],[3],[3],[3]]

If you're using 1.7?+, you can give a block to the constructor which is 
evaluated to get the value of each cell:

a = Array.new(5) {[]}
a[2] << 3
a  # [[],[],[3],[],[]]

A similar thing seems to exist for Hash:

h = Hash.new([])
h[:a] <<= :x
h[:b] <<= :y
h[:a]  #[:x, :y]
h = Hash.new {[]}
h[:a] <<= :x
h[:b] <<= :y
h[:a]  # [:x]

Strange thing is I can't find this documented anywhere.  Not even at 
http://www.pragmaticprogrammer.com/ruby/new_features.html.  Shouldn't this 
be added there?