From: Robert Klemme Date: 2007-09-03T20:08:43+09:00 Subject: Re: assigning to hash keys when there is a default value? 2007/9/3, dblack@wobblini.net : > Hi -- > > On Mon, 3 Sep 2007, 7stud -- wrote: > > > Can someone explain why there is a difference in the second line of > > output for the two hashes: > > > > h = Hash.new(5) > > > > puts h[2] > > > > h[2] ||= 10 > > p h > > > > #---------- > > puts > > #---------- > > > > h = Hash.new > > > > puts h[2] > > > > h[2] ||= 10 > > p h > > > > ---output:-- > > 5 > > {} > > > > nil > > {2=>10} > > x ||= y is, I think, always supposed to be exactly equivalent to > x = x || y, so that line in your first hash should be equivalent to: > > h[2] = 5 || 10 > > which should assign 5 to h[2]. It looks to me like you've found a bug. > I can't think of any reason (and I really hope there isn't one, > because having an exception to that ||= rule would be very messy) why > using a default hash value would make any difference here. It's still > 5 || 10 on the rhs, and it's still just an assignment. I can't point my finger on it but I believe x||=y is equivalent to "x=y unless x" instead of "x=x||y". It seems to be more reasonable to skip the assignment altogether if the value is true equivalent already. That would also explain behavior much better. :-) Note also: $ ruby -e 'h=Hash.new 2;set_trace_func lambda {|*a| p a}; h[4]||=10' ["line", "-e", 1, nil, #, false] ["c-call", "-e", 1, :[], #, Hash] ["c-call", "-e", 1, :default, #, Hash] ["c-return", "-e", 1, :default, #, Hash] ["c-return", "-e", 1, :[], #, Hash] $ ruby -e 'h=Hash.new 2;set_trace_func lambda {|*a| p a}; h[4]=h[4]||10' ["line", "-e", 1, nil, #, false] ["c-call", "-e", 1, :[], #, Hash] ["c-call", "-e", 1, :default, #, Hash] ["c-return", "-e", 1, :default, #, Hash] ["c-return", "-e", 1, :[], #, Hash] ["c-call", "-e", 1, :[]=, #, Hash] ["c-return", "-e", 1, :[]=, #, Hash] There is no assignment in the first piece. Kind regards robert