From: 7stud -- Date: 2009-09-12T03:07:10+09:00 Subject: Re: populating a hash from an array using inject Glenn Jackman wrote: > At 2009-09-10 09:16PM, "7stud --" wrote: >> > p h >> > >> > {"A"=>[10, 20], "B"=>[10, 20]} >> > >> >> Yep, ruby hands you a reference to the same array over and over >> again...when you try to access non-existent keys. > > While I thank you for takking the time, I can't say I'm enlightened by > your explanation. What's the real difference between the blocks > > bar = products.inject(Hash.new([])) {|h,p| h[p.category] << p; h} > baz = products.inject(Hash.new([])) {|h,p| h[p.category] += [p]; h} > > Is it because += explicitly assigns a new object to the hash key? Yes. When the key doesn't exist the first line is equivalent to: bar = products.inject(Hash.new([])) {|h,p| [] << p; h} which does nothing to the hash--all it does is append p to an empty array, and then the empty array is discarded. The second line is equivalent to: baz = products.inject(Hash.new([])) {|h,p| h[p.category] = h[p.category] + [p]; h} If you access a non-existent key, say h["A"], then that line is equivalent to baz = products.inject(Hash.new([])) {|h,p| h["A"] = [] + [p]; h} or baz = products.inject(Hash.new([])) {|h,p| h["A"] = [p]; h} which explicitly sets a key in the hash to the value [p], thereby altering the hash. -- Posted via http://www.ruby-forum.com/.