On Wed, Sep 03, 2003 at 12:13:19AM +0900, nord ehacedod wrote:
> This works, but there must be a more natural way to do
> this. Can someone point the way?

There's a new feature in 1.8.0 for it:

>   # create sub-hashes automatically
>   def [](n)
>      self[n]=HashAutoZero.new if super(n)==nil
>      super(n)
>   end

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

>   # "values" in sub-hash automatically have initial
> value 0
>   class HashAutoZero < Hash
>     def [](n)
>        self[n]=0 if super(n)==nil
>        super(n)
>     end
>   end

h2 = Hash.new(0)

although this means that unset values read out as 0, it does not autovivify
the value in the hash. If you need that, then:

h2 = Hash.new { |me,k| me[k]=0 }

Combining these two:

irb(main):020:0> h = Hash.new { |h1,k1| h1[k1] = Hash.new { |h2,k2| h2[k2]=0 } }
=> {}
irb(main):021:0> h['fred']
=> {}
irb(main):022:0> h
=> {"fred"=>{}}
irb(main):023:0> h['foo']['bar']
=> 0
irb(main):024:0> h
=> {"fred"=>{}, "foo"=>{"bar"=>0}}

Regards,

Brian.