From: "David A. Black" Date: 2009-09-11T20:45:48+09:00 Subject: Re: populating a hash from an array using inject Hi -- On Fri, 11 Sep 2009, Glenn Jackman wrote: > At 2009-09-10 09:16PM, "7stud --" wrote: >> 7stud -- wrote: >>> h = Hash.new([]) >>> >>> h["A"] = h["A"] << 10 #==>[10] >>> >>> h["B"] = h["B"] << 20 #==>[20] >>> >>> Look what happens: >>> >>> >>> 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. Here's another way to look at it: array = [] hash = Hash.new(array) hash[:x] << 1 # equivalent to: array << 1 hash[:y] << 2 # equivalent to: array << 2 hash[:z] += [:a,:b,:c] # equivalent to: h[:z] = array + [:a,:b,:c] David -- David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com Ruby/Rails training, mentoring, consulting, code-review Latest book: The Well-Grounded Rubyist (http://www.manning.com/black2) September Ruby training in NJ has been POSTPONED. Details to follow.