# Please explain nuances of ||=

**URL:** <https://www.ruby-forum.com/t/please-explain-nuances-of/136398>\
**Category:** Ruby\
**Created:** [May 1, 2008, 6:20pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398 "2008-05-01T18:20:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 6:20pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/1 "2008-05-01T18:20:27Z")

</div>

I am reading some of the ruby files in rails and I an seeing the ||=  
method used a lot.  
knowing ruby the way I do, I realize that she has lots of magical  
surprises and I really want to get to know this girl!

Consider the initialize method of resources.rb

51 def initialize(entities, options)  
52 @plural ||= entities  
53 @singular ||= options[:singular] ||  
plural.to\_s.singularize  
54 @path\_segment = options.delete(:as) || @plural  
55  
56 @options = options  
57  
58 arrange\_actions  
59 add\_default\_actions  
60 set\_prefixes  
61 end

(OK, so one iddy bitty part of this is a rails question, and dangit,  
this is a ruby forum, but you guys are smarter and have better  
haircuts)

Question (1)  
After several hours of searching I find virtually nothing that fully  
explains the line  
@singular ||= options[:singular] || plural.to\_s.singularize

I think know what is does, It assigns @singular a value for a  
“singular named” controller if the options hash contains the  
symbol :singular. I am looking more for a full description of how ||=  
and it’s friends like &&= actually work.

my current understanding shows me:  
@singular = (options[:singular]) or (plural.to\_s.singularize)

but the full logic seems to be more like:  
if options contains a symbol named :singular then  
@singular = plural.to\_s.singularize  
end if

But what is the value of @singular if there is no :singular symbol?  
nil?

What I think is going on is a lot more like an IF statement than a OR  
statement.

Question (2)  
in the line: @plural ||= entities  
if entities is (false?, nil? something that fails “OR”) what happens  
to @plural?

Once again, the ||= seems more like an “equals If” statement rather  
than an “equals Or” statement.

Question (3)  
@path\_segment = options.delete(:as) || @plural  
So @path\_segment is assigned either the return from the delete  
operation (:as) ? or the plural name of the controller. Is that  
correct? Where in a common resourceful routes mapping is there an :as?

Thanks in advance for any help.

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 6:34pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/2 "2008-05-01T18:34:39Z")

</div>

You’re close on some, right on some.

@plural||=entries  
simply says, if @plural is nil or false (someone correct me if I’m a  
tad off), set it to entries, otherwise don’t do anything.

For @singular, close but… you need the or  
@singular ||= ((options[:singular]) or (plural.to\_s.singularize))

@path\_segment is a little bit stranger, but for me it harkens back to c  
days.  
if options.delete(:as) returns any value that evalutes to true  
(anything but nil or false), @path\_segment is set to that value. If  
options.delete(:as) fails or returns nil, @path\_segment is set to  
@plural.

Does that help?

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 6:37pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/3 "2008-05-01T18:37:36Z")

</div>

On 2008-05-01, Ruby F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I am reading some of the ruby files in rails and I an seeing the ||=  
> method used a lot.

There’s a nice discussion at  
URL:http://talklikeaduck.denhaven2.com/articles/2008/04/26/x-y-redux.

Regards,

Jeremy H.

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 6:57pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/4 "2008-05-01T18:57:06Z")

</div>

Hi –

On Fri, 2 May 2008, Ruby F. wrote:

> I am reading some of the ruby files in rails and I an seeing the ||=  
> method used a lot.  
> knowing ruby the way I do, I realize that she has lots of magical  
> surprises and I really want to get to know this girl!

x ||= y means: x || x = y

The difference is that x ||= y won’t complain if x is undefined,  
whereas if you type x || x = y and there’s no x in scope, it will. The  
basic idea is that if x is (a) undefined (b) nil (c) false, you want  
to set it to y. Otherwise, you want to leave it alone. The whole  
expression evaluates to x, after the assignment has happened (or not).

See [http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case](http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case) for  
more.

David

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 9:06pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/5 "2008-05-01T21:06:57Z")

</div>

- David A. Black [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (18:56) schrieb:

> Hi –
> 
> On Fri, 2 May 2008, Ruby F. wrote:
> 
> > I am reading some of the ruby files in rails and I an seeing the ||=  
> > method used a lot.  
> > knowing ruby the way I do, I realize that she has lots of magical  
> > surprises and I really want to get to know this girl!
> 
> x ||= y means: x || x = y

No, it means: x = x || y

> The difference is that x ||= y won’t complain if x is undefined,

That’s because = does the same.

mfg, simon … l

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 7:10pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/6 "2008-05-01T19:10:38Z")

</div>

Yes, Thank you,

That is very helpful.

Google seems to puke on “||=” so I wasn’t getting any search results.

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 9:25pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/7 "2008-05-01T21:25:46Z")

</div>

On 01.05.2008 20:54, Simon K. wrote:

> > x ||= y means: x || x = y
> 
> No, it means: x = x || y

I believe you are wrong.

irb(main):001:0\> h={}  
=\> {}  
irb(main):002:0\> h=Hash.new true  
=\> {}  
irb(main):003:0\> h[1]  
=\> true  
irb(main):004:0\> h[1] ||= 10  
=\> true  
irb(main):005:0\> h  
=\> {}  
irb(main):006:0\>

If you were right, h would look differently:

irb(main):008:0\> h=Hash.new true  
=\> {}  
irb(main):009:0\> h[1] = h[1] || 10  
=\> true  
irb(main):010:0\> h  
=\> {1=\>true}

The same topic has been discussed exhaustively a few days ago.

Cheers

robert

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 10:13pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/8 "2008-05-01T22:13:12Z")

</div>

Hi –

On Fri, 2 May 2008, Simon K. wrote:

> > x ||= y means: x || x = y
> 
> No, it means: x = x || y

This is becoming a bit of a perma-thread 🙂

See Robert K.'s answer, and also have a look at the blog post I  
mentioned in my response. It’s about exactly why x = x || y is not the  
right expansion for x ||= y.

David

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 10:39pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/9 "2008-05-01T22:39:47Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

David A. Black wrote:

|\> No, it means: x = x || y  
|  
| This is becoming a bit of a perma-thread 🙂  
|  
| See Robert K.'s answer, and also have a look at the blog post I  
| mentioned in my response. It’s about exactly why x = x || y is not the  
| right expansion for x ||= y.

x ||= y expands into x = x || y, since x == 1 expands to x = x + 1, and  
we have no reason to expect ||= to behave differently (MPLOS).

Also, it works as expected if the expansion x = x || y is correct. After  
all:

‘The or and || operators evaluate their first operand. If true, the  
expression returns the value of their first operand; otherwise, the  
expression returns the value of the second operand.’  
Programming Ruby, 2nd Edition (p. 326).

And Robert’s answer works the way it works because the Hash has a  
default value set, which doesn’t equate to false or nil. If you override  
the default value by setting the value to false, the assignment works  
again as expected.

* * *

Phillip G.  
Twitter: [twitter.com/cynicalryan](http://twitter.com/cynicalryan)  
Blog: [http://justarubyist.blogspot.com](http://justarubyist.blogspot.com)

Zero raised to the nth power remains zero.  
~ – Pop Baslim  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.8 (MingW32)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iEYEARECAAYFAkgaKhoACgkQbtAgaoJTgL/LkgCeMqByMe50+mJx/j8vV3KC612p  
lF4AnAz+GVlTLKNPdcjZnsFbbTTwHebv  
=Tkje  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 10:43pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/10 "2008-05-01T22:43:17Z")

</div>

HI –

On Fri, 2 May 2008, Phillip G. wrote:

> |\>\>  
> | irb(main):001:0\> h={}  
> |  
> |  
> Quoth Joshua B.:  
> =\> {}  
> irb(main):007:0\> h[3] = h[3] || ‘not false’  
> =\> “not false”

The question, though, is what x ||= y expands to. Robert’s point is  
that if you say it expands to x = x || y, that doesn’t account for  
what happens with a hash that has a non-false default value.

Mind you, x || x = y doesn’t account (as I mentioned) for the fact  
that if x isn’t defined, you can’t use that syntax. x ||= y is really  
its own thing, and doesn’t expand 100% of the time to anything. But x  
|| x = y, if you allow for the undefined x thing, describes all of the  
behaviors, including the hash edge case.

David

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 10:46pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/11 "2008-05-01T22:46:49Z")

</div>

Knowing ruby the way I do, I realize that she has lots of magical  
surprises and I really want to get to know this girl!

Happens every time! Bring a girl into the bar and a fight breaks out.

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 10:26pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/12 "2008-05-01T22:26:10Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Robert K. wrote:  
| On 01.05.2008 20:54, Simon K. wrote:  
|\> \* David A. Black [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (18:56) schrieb:  
|\>  
|\>\> Hi –  
|\>\>  
|\>\> On Fri, 2 May 2008, Ruby F. wrote:  
|\>\>  
|\>\>\> I am reading some of the ruby files in rails and I an seeing the ||=  
|\>\>\> method used a lot.  
|\>\>\> knowing ruby the way I do, I realize that she has lots of magical  
|\>\>\> surprises and I really want to get to know this girl!  
|\>\> x ||= y means: x || x = y  
|\>  
|\> No, it means: x = x || y  
|  
| I believe you are wrong.  
|  
| irb(main):001:0\> h={}  
| =\> {}  
| irb(main):002:0\> h=Hash.new true  
| =\> {}  
| irb(main):003:0\> h[1]  
| =\> true  
| irb(main):004:0\> h[1] ||= 10  
| =\> true  
| irb(main):005:0\> h  
| =\> {}  
| irb(main):006:0\>  
|  
| If you were right, h would look differently:  
|  
| irb(main):008:0\> h=Hash.new true  
| =\> {}  
| irb(main):009:0\> h[1] = h[1] || 10  
| =\> true  
| irb(main):010:0\> h  
| =\> {1=\>true}  
|  
| The same topic has been discussed exhaustively a few days ago.  
|  
| Cheers  
|  
| robert  
|  
|

You are wrong, too, though.

I refer you to Ruby-Talk 297145[0]:

Quoth Joshua B.:  
‘The only reason that Chris’ example behaves like “x || x = 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). ’

x = x || ‘a value’ works when x is nil or false. Once the Hash has a  
default value, it shouldn’t be false, much less nil.

See:

irb(main):001:0\> h = Hash.new  
=\> {}  
irb(main):002:0\> h[1].nil?  
=\> true  
irb(main):003:0\> h[1] = h[1] || 10  
=\> 10  
irb(main):004:0\> h[2] = ‘not nil’  
=\> “not nil”  
irb(main):005:0\> h[2] = h[2] || ‘a value’  
=\> “not nil”  
irb(main):006:0\> h[3] = false  
=\> false  
irb(main):007:0\> h[3] = h[3] || ‘not false’  
=\> “not false”

[0] [http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/297145](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/297145)

* * *

Phillip G.  
Twitter: [twitter.com/cynicalryan](http://twitter.com/cynicalryan)  
Blog: [http://justarubyist.blogspot.com](http://justarubyist.blogspot.com)

~ Calvin: I’m a genius, but I’m a misunderstood genius. Hobbes:  
What’s  
misunderstood about you? Calvin: Nobody thinks I’m a genius. – Calvin  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.8 (MingW32)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iEYEARECAAYFAkgaJxMACgkQbtAgaoJTgL8e0QCdHbW1PniEGPZSlC9Api4lIL7u  
viAAnis9nThp0JAXQEwGWU+JEM5s+ssL  
=3HqG  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 10:50pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/13 "2008-05-01T22:50:21Z")

</div>

Hi –

On Fri, 2 May 2008, Phillip G. wrote:

> | mentioned in my response. It’s about exactly why x = x || y is not the  
> | right expansion for x ||= y.
> 
> x ||= y expands into x = x || y, since x == 1 expands to x = x + 1, and

I think you mean +=.

> we have no reason to expect ||= to behave differently (MPLOS).

That’s really where this thread always starts, though: why doesn’t it  
behave like x = x || y in every case? Anyway, the thing about MPOLS is  
that you and I can’t invoke it 🙂 It was actually Matz who showed me  
the x || x = y expansion (most recently at EuRuKo, where I talked to  
him about it because I wanted to make sure the corrections I made to  
my blog post had made it correct).

> the default value by setting the value to false, the assignment works  
> again as expected.

Right, but hashes are allowed to have default values. So an  
explanation that accounts for that case is better than one that  
doesn’t. The point is that if you do a drop-in replacement x = x || y  
you get a different result from ||=, and with x || x = y you don’t.  
That means, definitively I think, that the latter is a more correct  
expansion. (I’m not sure how it couldn’t mean that.)

Anyway, this is at least the third thread on this in recent months,  
and I’ve written my blog post (and correction follow-up 🙂 about it.  
I think I’m about ||='d out.

David

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 11:11pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/14 "2008-05-01T23:11:30Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

David A. Black wrote:

|\> x ||= y expands into x = x || y, since x == 1 expands to x = x + 1, and  
|  
| I think you mean +=.

Yes, indeed.

|\> we have no reason to expect ||= to behave differently (MPLOS).  
|  
| That’s really where this thread always starts, though: why doesn’t it  
| behave like x = x || y in every case? Anyway, the thing about MPOLS is  
| that you and I can’t invoke it 🙂 It was actually Matz who showed me  
| the x || x = y expansion (most recently at EuRuKo, where I talked to  
| him about it because I wanted to make sure the corrections I made to  
| my blog post had made it correct).

It doesn’t behave that way because classes can implement and override  
behavior. Which can lead to surprising results, and sometimes  
pathological cases of Monkeypatching. 😉

Also, the MPLOS helps as a guideline, not as a hard and fast rule. 🙂

|\> And Robert’s answer works the way it works because the Hash has a  
|\> default value set, which doesn’t equate to false or nil. If you override  
|\> the default value by setting the value to false, the assignment works  
|\> again as expected.  
|  
| Right, but hashes are allowed to have default values. So an  
| explanation that accounts for that case is better than one that  
| doesn’t. The point is that if you do a drop-in replacement x = x || y  
| you get a different result from ||=, and with x || x = y you don’t.  
| That means, definitively I think, that the latter is a more correct  
| expansion. (I’m not sure how it couldn’t mean that.)

However, a default value results in the Hash not evaluating to nil or  
false. Which is required for || and OR to use their _second_ operand  
(since it otherwise uses the first operand), so x || x = y cannot work.  
Unless we get into precedence issues here, I guess.

| Anyway, this is at least the third thread on this in recent months,  
| and I’ve written my blog post (and correction follow-up 🙂 about it.  
| I think I’m about ||='d out.

So am I.

* * *

Phillip G.  
Twitter: [twitter.com/cynicalryan](http://twitter.com/cynicalryan)  
Blog: [http://justarubyist.blogspot.com](http://justarubyist.blogspot.com)

~ Why do we drink cow’s milk? Who was the first guy who first looked  
at  
a cow and said “I think I’ll drink whatever comes out of these things  
when I squeeze 'em!”? – Calvin  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.8 (MingW32)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iEYEARECAAYFAkgaMdsACgkQbtAgaoJTgL+7ggCfZvH1Zt26JJtfKA+uPdd28oPV  
/28AnjWINp8XwuVrx00X2qRT/LCtz/Ny  
=CldW  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 2, 2008, 12:00am UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/15 "2008-05-02T00:00:04Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

David A. Black wrote:  
| Hi –  
|  
| On Fri, 2 May 2008, Phillip G. wrote:  
|  
| Whoops – sorry 🙂

As if. 😛

| I actually have a feeling we’re talking at cross-purposes, and that  
| I’m somehow not getting something. All I’m saying is that h[x] ||=  
| value is the same as h[x] || h[x] = value, for any hash h and any key  
| x. That can be demonstrated easily (as Robert did) just by  
| substituting one expression for the other. It’s an unusual case, but  
| it’s legal. I’m not sure what would be needed beyond that to  
| demonstrate that x = x || y is not a drop-in replacement for x ||= y.

Yeah, I’m taking the Bird’s Eye View on it all, essentially saying: 'it  
works like this almost always, but Hash is a special case, since it has  
default values [or whatever the implementation detail is, that makes  
Hash work differently]).

* * *

Phillip G.  
Twitter: [twitter.com/cynicalryan](http://twitter.com/cynicalryan)  
Blog: [http://justarubyist.blogspot.com](http://justarubyist.blogspot.com)

~ “Endorsing products is the American way of expressing  
individuality.”

- -Calvin  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.8 (MingW32)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iEYEARECAAYFAkgaPUgACgkQbtAgaoJTgL/kQQCggPuXLrZqT/zmBBALUKUY1/4h  
P44An2JhhO4GiMgkGP07DULeaV5d5a+u  
=nH6/  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 2, 2008, 12:11am UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/16 "2008-05-02T00:11:51Z")

</div>

Hi –

On Fri, 2 May 2008, Phillip G. wrote:

> As if. 😛  
> works like this almost always, but Hash is a special case, since it has  
> default values [or whatever the implementation detail is, that makes  
> Hash work differently]).

It’s possible to generalize it; someone in one of the threads wrote a  
class that showed the same behavior, but I can’t remember the details.  
I do wish it were otherwise; it’s definitely unexpected, I think.

David

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 2, 2008, 12:52am UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/17 "2008-05-02T00:52:12Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

David A. Black wrote:  
| Hi –  
|  
| It’s possible to generalize it; someone in one of the threads wrote a  
| class that showed the same behavior, but I can’t remember the details.  
| I do wish it were otherwise; it’s definitely unexpected, I think.

Well, it is unexpected if you forget about the default value for Hash,  
for example.

So, I agree: On first sight it _is_ unintuitive. Once you think about,  
though…

As a tangent:  
I’ve just checked my copy of The Ruby Way, and its ‘Training your  
intuition’ sub-chapter. This gotcha isn’t part of it. ☹

Maybe it could be added for the next edition (unless Ruby 1.9/2.0 is the  
reason for the new edition, and the ambiguity/idiosyncrasy is removed in  
the new version of Ruby by then).

* * *

Phillip G.  
Twitter: [twitter.com/cynicalryan](http://twitter.com/cynicalryan)  
Blog: [http://justarubyist.blogspot.com](http://justarubyist.blogspot.com)

~ “Oops, I always forget the purpose of competition is to divide  
people  
into  
winners and losers.” -Hobbes being sarcastic  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.8 (MingW32)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iEYEARECAAYFAkgaSVoACgkQbtAgaoJTgL+ExwCgjbqnS7cqvvMHhPy5PRt8DX9Y  
nOkAoJF5YjaZuXQA71NhvdpEe/9zlFdx  
=sYWv  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 2, 2008, 12:59am UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/18 "2008-05-02T00:59:14Z")

</div>

2008/5/2 Ruby F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 2, 2008, 1:00am UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/19 "2008-05-02T01:00:24Z")

</div>

David A. Black wrote:

> It’s possible to generalize it; someone in one of the threads wrote a  
> class that showed the same behavior, but I can’t remember the details.

[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/297185](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/297185)

---

<div class="post-metadata">

**Author:** ![rubyfreak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/e9c0ed/32.png) [@rubyfreak](https://www.ruby-forum.com/u/rubyfreak)\
**Post date:** [May 1, 2008, 11:28pm UTC](https://www.ruby-forum.com/t/please-explain-nuances-of/136398/20 "2008-05-01T23:28:27Z")

</div>

Hi –

On Fri, 2 May 2008, Phillip G. wrote:

> However, a default value results in the Hash not evaluating to nil or  
> false. Which is required for || and OR to use their _second_ operand  
> (since it otherwise uses the first operand), so x || x = y cannot work.  
> Unless we get into precedence issues here, I guess.

It depends what you mean by work 🙂 See Robert’s example.

> | Anyway, this is at least the third thread on this in recent months,  
> | and I’ve written my blog post (and correction follow-up 🙂 about it.  
> | I think I’m about ||='d out.
> 
> So am I.

Whoops – sorry 🙂

I actually have a feeling we’re talking at cross-purposes, and that  
I’m somehow not getting something. All I’m saying is that h[x] ||=  
value is the same as h[x] || h[x] = value, for any hash h and any key  
x. That can be demonstrated easily (as Robert did) just by  
substituting one expression for the other. It’s an unusual case, but  
it’s legal. I’m not sure what would be needed beyond that to  
demonstrate that x = x || y is not a drop-in replacement for x ||= y.

David

[Next page](https://www.ruby-forum.com/t/please-explain-nuances-of/136398.md?page=2)
