From: "David A. Black" Date: 2008-04-05T19:20:26+09:00 Subject: Re: The ||= assignment operator --1926193751-626661992-1207390825=:19443 Content-Type: MULTIPART/MIXED; BOUNDARY="1926193751-626661992-1207390825=:19443" This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. --1926193751-626661992-1207390825=:19443 Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE HI -- On Sat, 5 Apr 2008, Joshua Ballanco wrote: > Pe=C3=B1a, Botp wrote: >> From: Chris Shea [mailto:cmshea@gmail.com] >> # It's better to think of x ||=3D "ruby" as x || x =3D "ruby". >> # >> # -- >> # h =3D Hash.new('default value') >> # >> # h[:test] ||=3D 'assigned value' >> # h # =3D> {} >> # >> # # same as: >> # h[:test] || h[:test] =3D 'assigned value' >> # h # =3D> {} >> # >> # # not: >> # h[:test] =3D h[:test] || 'assigned value' >> # h # =3D> {:test=3D>"default value"} >> >> >> i'd say that's a bug in design (unless x+=3D1 is now x+x=3D1 ;) >> >> kind regards -botp > > Not at all. Rather, this is just a subtle misunderstanding of how hash > is implemented. Consider the following: > >>> h =3D Hash.new > =3D> {} >>> h[:test] ||=3D 'testing without default' > =3D> "testing without default" >>> h > =3D> {:test=3D>"testing without default"} >>> h =3D Hash.new('default value') > =3D> {} >>> h[:test] ||=3D 'testing with default' > =3D> "default value" >>> h > =3D> {} > > The only reason that Chris' example behaves like "x || x =3D stuff" is > because he's defined a default value for the hash. If you set a default > value, than you'll never have a keyed value be empty (i.e. nil). The only expansion that accounts for all cases of the ||=3D operator is x || x =3D stuff. If it were actually x =3D x || stuff, then this: irb(main):005:0> h =3D Hash.new(1) =3D> {} irb(main):006:0> h[:x] =3D h[:x] || 2 =3D> 1 irb(main):007:0> h =3D> {:x=3D>1} would behave the same as this: irb(main):008:0> h[:y] ||=3D 2 =3D> 1 irb(main):009:0> h =3D> {:x=3D>1} but it doesn't. But ||=3D does behave like this: irb(main):010:0> h[:z] || h[:z] =3D 2 =3D> 1 irb(main):011:0> h =3D> {:x=3D>1} In other words, x ||=3D y =3D=3D x || x =3D y, or something :-) I personally would like to see it act like x =3D x || y, though I think hash defaults are the only case where the difference actually makes a difference. David --=20 Rails training from David A. Black and Ruby Power and Light: ADVANCING WITH RAILS April 14-17 New York City INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin See http://www.rubypal.com for details and updates! --1926193751-626661992-1207390825=:19443-- --1926193751-626661992-1207390825=:19443--