2010/1/26 Jes=FAs Gabriel y Gal=E1n <jgabrielygalan / gmail.com>

> On Tue, Jan 26, 2010 at 3:29 PM, Glen Holcomb <damnbigman / gmail.com>
> wrote:
> > 2010/1/26 Jes=FAs Gabriel y Gal=E1n <jgabrielygalan / gmail.com>
> >
> >> On Mon, Jan 25, 2010 at 10:49 PM, Glen Holcomb <damnbigman / gmail.com>
> >> 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 le=
af
> >> 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
> the
> >> proxy object"
> >>                 @hash[@key] =3D Hash.new {|hash,key|
> ProxyDefault.new(hash,
> >> key)}
> >>                 puts "the hash is: #{@hash.inspect} after replacing th=
e
> >> 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 a=
m
> > 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 t=
he
> > 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 << cal=
l
> at
> > that level with a new single item array.
>
> I understood your question, so this means I explained myself really badly
> :-).
> When you do this:
>
> h[1] << 4
>
> The following things happen:
>
> - The method [] of h is called with parameter 1
> - The hash detects that there's no entry for that key, and so calls
> the default proc
> - The default proc inserts a Proxy object in the hash for that key
> (this proxy object remembers the hash and the key)
> - The result of the default proc (which is the proxy object itself) is
> returned
> - The method << with parameter 4 is called on the proxy object
> - That method removes the proxy object from the hash and replaces
> itself with an array with element 4 inside.
>
> From now on, every time you call h[1] there is actually a value in the
> hash, which is the array created by the proxy, and so the hash doesn't
> call the default proc anymore, and no other proxy object is involved.
> Subsequent calls to h[1] << some_value will actually call the <<
> method of the array.
>
> Hope this clears up the issue a little bit more.
>
> Jesus.
>
>
No, you didn't acutally.  I just wasn't thinking about it properly.  When I
actually think about your explanation further the whole *no more proxy
object* makes perfect sense and answers my question.

Thanks for your patience and help Jesus.  It is appreciated.

--=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)