Robert Klemme
9/3/2007 11:09:00 AM
2007/9/3, dblack@wobblini.net <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, #<Binding:0x1002ff48>, false]
["c-call", "-e", 1, :[], #<Binding:0x1002ff0c>, Hash]
["c-call", "-e", 1, :default, #<Binding:0x1002fdf4>, Hash]
["c-return", "-e", 1, :default, #<Binding:0x1002fcf0>, Hash]
["c-return", "-e", 1, :[], #<Binding:0x1002fc00>, Hash]
$ ruby -e 'h=Hash.new 2;set_trace_func lambda {|*a| p a}; h[4]=h[4]||10'
["line", "-e", 1, nil, #<Binding:0x1002fee4>, false]
["c-call", "-e", 1, :[], #<Binding:0x1002fea8>, Hash]
["c-call", "-e", 1, :default, #<Binding:0x1002fd90>, Hash]
["c-return", "-e", 1, :default, #<Binding:0x1002fc8c>, Hash]
["c-return", "-e", 1, :[], #<Binding:0x1002fb9c>, Hash]
["c-call", "-e", 1, :[]=, #<Binding:0x1002faac>, Hash]
["c-return", "-e", 1, :[]=, #<Binding:0x1002f9bc>, Hash]
There is no assignment in the first piece.
Kind regards
robert