Directly from the rdoc:

     "If a block is
      specified, it will be called with the hash object and the key, and
      should return the default value. It is the block's responsibility
      to store the value in the hash if required."

So you want:

irb>   trt_hash = Hash.new {|h,k| h[k] = Hash.new &h.default_proc }
=> {}
irb> trt_hash[:a][:b][:c] = "hi"
=> "hi"
irb> trt_hash
=> {:a=>{:b=>{:c=>"hi"}}}

-Rob

Rob Biedenharn		http://agileconsultingllc.com
Rob / AgileConsultingLLC.com

On Jan 2, 2009, at 11:15 PM, Glenn wrote:

> Hi,
>
> Suppose I want to create a hash, which has a couple of elements with  
> strings as the keys and the values of each of the elements were  
> hashes themselves, and they each had a few elements, like this:
>
> trt_hash = Hash.new( {} )
>
> trt_hash['a'] = { :x => 0, :y => 0, :z => 0 }
> trt_hash['b'] = { :x => 0, :y => 0, :z => 0 }
>
> If I increment one of the values of the hash within the hash, like  
> this, it works fine:
>
> trt_hash['a'][:z] += 100
> puts trt_hash['Hi'][:z] = 10
> puts trt_hash.inspect
>
> I get: {"a"=>{:z=>100, :x=>0, :y=>0}, "b"=>{:z=>0, :x=>0, :y=>0}},  
> which is what I expected.
>
> But if I try to add another key to trt_hash and increment one of the  
> keys of its hash, like this:
>
> trt_hash['c'][:z] += 100
> puts trt_hash.inspect
>
> there is no error, but there is also no reference to the 'c' key  
> when I print trt_hash.
>
> Also, if I try this, I get an error:
>
> trt_hash['a'][:w] += 100
> puts trt_hash.inspect
>
> The key above is 'a', which exists, but :w in the 'a' hash does not  
> exist, so I get the following error:
>
> undefined method `+' for nil:NilClass (NoMethodError)
>
> I want to put able to add elements to trt_has at will and have them  
> default to an empty hash, and I want to be able to modify the hash  
> within the hash without predefining anything.  I feel like this  
> would work if I set up the hash and the hash within the hash with  
> the proper defaults, but I do not know how to do that.
>
> I thought if I defined trt_hash like this:
>
> trt_hash = Hash.new( Hash.new(0))
>
> I would be able to add any key to trt_hash and its value would have  
> a default of an empty hash, and then I'd be able to add any element  
> I wanted to the nested hash, and its default would be 0.  But this  
> does not seem to work.
>
> Any suggestions?
>
> Sorry if this email is unclear.  If it is, please let me know and I  
> will try to clarify.
>
> Thanks!
>
> Glenn