From: "Jesús Gabriel y Galán" Date: 2010-01-26T18:01:14+09:00 Subject: Re: Nested hash with arrays for default value On Mon, Jan 25, 2010 at 10:49 PM, Glen Holcomb wrote: > Exactly, infinite depth would be nice as it would make a more temporally > portable solution. With it, you have infinite depth, until in a branch you decide to stop by appending (<<) a value. Then you fix the depth of that branch. > The proxy looks to be working great.  I am a bit > confused as to why the << method in the proxy doesn't overwrite a leaf with > a new array though.  I'm not complaining as it works the way I want it to, > I'm just perplexed. When you access h[1][2][3], a proxy object is inserted in the hash for that key. The proxy object remembers the hash and the key. When you call << on the proxy object, it replaces itself in the hash with an empty array, to which it appends the value. So further calls to h[1][2][3] will return that array and no proxy objects anymore. It works the same for the upper levels: calling h[1] inserts a proxy in the hash. When you call [] on it (for example h[1][2]) it replaces h[1] with a hash. Maybe this clarifies a bit more: /temp$ cat nested_hash_array.rb && ruby nested_hash_array.rb class ProxyDefault def initialize hash, key @hash = hash @key = key end def [](key) puts "the hash is: #{@hash.inspect} when calling [] on the proxy object" @hash[@key] = Hash.new {|hash,key| ProxyDefault.new(hash, key)} puts "the hash is: #{@hash.inspect} after replacing the proxy with a hash" @hash[@key][key] end def << value puts "the hash is: #{@hash.inspect} when calling << on the proxy object" @hash[@key] = [value] puts "the hash is: #{@hash.inspect} after replacing the proxy with an array" @hash[@key] end end h = Hash.new {|hash,value| ProxyDefault.new(hash, value)} h[1][2] << "value" p h p h[1][2] the hash is: {} when calling [] on the proxy object the hash is: {1=>{}} after replacing the proxy with a hash the hash is: {} when calling << on the proxy object the hash is: {2=>["value"]} after replacing the proxy with an array {1=>{2=>["value"]}} ["value"] Jesus.