On Mon, 22 Jan 2007, Ken Bloom wrote: >> >> For more discussion, search for "autovivify hash" on the list... >> > > Then the inject trick becomes > > pr = lambda {|h,k| h[k] = Hash.new(&pr)} > z=Hash.new(&pr) > s = "a/b/c" > s.split("/").inject(z){|ha,co| ha[co]} > s = "a/b/d" > s.split("/").inject(z){|ha,co| ha[co]} > s = "a/d/e" > s.split("/").inject(z){|ha,co| ha[co]} > s = "c/a/t" > s.split("/").inject(z){|ha,co| ha[co]} > p z > > For some reason you can't name the hash h, otherwise the parameter > assignment in the proc will override it. Why is that, and is there any way > to avoid it? > i think it's less overhead to simply name the top hash and return it harp:~ > cat a.rb p( 'a/b/c'.split('/').inject(r={}){|h,k| h[k] = h={}} && r ) harp:~ > ruby a.rb {"a"=>{"b"=>{"c"=>{}}}} > > This is what you really wanted because you wanted a really easy way to merge > all of these paths together into one hash, whereas if you constructed the > hashes separately then merged them you'd be losing data. Try the following > to see what I mean. > > > h1={'a'=>{'b'=>{'c'=>{}}}} > h2={'a'=>{'b'=>{'d'=>{}}}} > h3={'a'=>{'c'=>{'e'=>{}}}} > h4={'c'=>{'a'=>{'t'=>{}}}} > p h1.merge(h2).merge(h3).merge(h4) > > All of the a/b branches are overwritten when 'a'=>{'c'...} is merged over > it. (And the second 'a'=>{'b'...} hash overwrites the first completely). > you are almost certainly right. good point! -a -- we can deny everything, except that we have the possibility of being better. simply reflect on that. - the dalai lama