From: Glen Holcomb Date: 2010-01-26T23:29:50+09:00 Subject: Re: Nested hash with arrays for default value --00151761ca482d0532047e121e14 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable 2010/1/26 Jes=FAs Gabriel y Gal=E1n > On Mon, Jan 25, 2010 at 10:49 PM, Glen Holcomb > wrote: > > > Exactly, infinite depth would be nice as it would make a more temporall= y > > 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 =3D hash > @key =3D key > end > > def [](key) > puts "the hash is: #{@hash.inspect} when calling [] on th= e > proxy object" > @hash[@key] =3D Hash.new {|hash,key| ProxyDefault.new(has= h, > 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] =3D [value] > puts "the hash is: #{@hash.inspect} after replacing the > proxy with an array" > @hash[@key] > end > end > > h =3D 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=3D>{}} after replacing the proxy with a hash > the hash is: {} when calling << on the proxy object > the hash is: {2=3D>["value"]} after replacing the proxy with an array > {1=3D>{2=3D>["value"]}} > ["value"] > > Jesus. > > Sorry, I should have been more specific when stating my confusion. I am confused as to why appending a second item into a leaf results in a multi-item array rather than a new array with only the second item. data[1][2][3] << 4 data[1][2][3] << 5 yields {1=3D>{2=3D>{3=3D>[4,5]}}} looing at the proxy I was expecting {1=3D>{2=3D>{3=3D>[5]}}} The behavior I'm seeing is what I want I just didn't expect it. From the code it looks like << assigns an array to the key then appends a value. I was expecting that to overwrite the array created with the first << call at that level with a new single item array. --=20 "Hey brother Christian with your high and mighty errand, Your actions speak so loud, I can=92t hear a word you=92re saying." -Greg Graffin (Bad Religion) --00151761ca482d0532047e121e14--