Logical OR in Ruby

I'm looking at some source code, to try and understand it.

There's a variable "weight", and then there's this call:

weight ||= 100

which I take to be equivalent to:

weight = weight || 100

(i.e., performing a logical OR between "weight" and 100).

What I think this code means, is that the value that will be assigned to
"weight" will be either (a) "weight" (if weight has already been
assigned) or else (b) if "weight" is presently nil, then the value 100
will be assigned to "weight" instead.

Is this correct?

···

--
Posted via http://www.ruby-forum.com/.

I'm looking at some source code, to try and understand it.

There's a variable "weight", and then there's this call:

weight ||= 100

which I take to be equivalent to:

weight = weight || 100

(i.e., performing a logical OR between "weight" and 100).

What I think this code means, is that the value that will be assigned to
"weight" will be either (a) "weight" (if weight has already been
assigned) or else (b) if "weight" is presently nil, then the value 100
will be assigned to "weight" instead.

Is this correct?

yes.

Generally, you'll find irb to be very helpful in finding things like this out:

irb(main):001:0> foo ||= 10
=> 10
irb(main):002:0> foo
=> 10
irb(main):003:0> foo ||=100
=> 10
irb(main):004:0> foo
=> 10
irb(main):005:0>

···

On Sun, Mar 20, 2011 at 10:09 PM, Paul Sholtz <paul.sholtz@gmail.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

--
thanks,
-pate
-------------------------
Don't judge those who choose to sin differently than you do

More specifically, || returns the second operand when the first operand is "falsy" -
logically false. Both nil and false are logically false.

So if "weight" were either nil OR false, then it would be reassigned.

Michael Edgar
adgar@carboni.ca
http://carboni.ca/

···

On Mar 21, 2011, at 12:09 AM, Paul Sholtz wrote:

What I think this code means, is that the value that will be assigned to
"weight" will be either (a) "weight" (if weight has already been
assigned) or else (b) if "weight" is presently nil, then the value 100
will be assigned to "weight" instead.

Is this correct?

I'm looking at some source code, to try and understand it.

[snip]

What I think this code means, is that the value that will be assigned to
"weight" will be either (a) "weight" (if weight has already been
assigned) or else (b) if "weight" is presently nil, then the value 100
will be assigned to "weight" instead.

Is this correct?

Yep, as others told you.

It might be worth pointing out, though, that Ruby might have a different
idea of falsehood compared to other languages you might be used to:

irb(main):001:0> puts "hey" if 0
hey
=> nil
irb(main):002:0> puts "hey" if
hey
=> nil

In Python 0 and would both evaluate to False.

···

On 21/03/2011 5.09, Paul Sholtz wrote:

--
Stefano

Not quite correct. there's a useful explanation here:
http://talklikeaduck.denhaven2.com/2008/04/26/x-y-redux
which (providing I'm reading Rick DeNatale's blog correctly) tells us that
(weight ||= 100) is expanded in Ruby as (weight || (weight = 100))
which *mostly* is the same as (weight = (weight || 100)), but might be
different (to quote Rick DeNatale) "when the left hand side is a
method call, to an accessor, or accessor-like method".

*** an extract from Rick DeNatale's blog post:

Matz explains that the real expansion of x ||= y is: x || x = y

The expectation that x ||= y is the same as x = x || y, does seem
reasonable to someone ‘coming from’ C or one of it’s derivative
languages. As far as I can determine, C introduced the notion of
assignment operators like += and -=. And K&R defined these assignment
operators as a shorthand for x = x + y, etc.

On the other hand, although C has logical operators || and && which,
like Ruby have ‘short-circuit’ evaluation, it doesn’t allow ||=, or
&&= as assignment operators.

Since || is a ‘short-circuit’ boolean operator, the right hand operand
expression is only evaluated if the left hand operand expression
evaluates to a logically false value, i.e. either nil or false.

The way that Matz included ||= as an assignment operator makes perfect
sense to me. The ||= assignment operator reserves the short-circuit
nature of ||.

*** Rick DeNatale also points out that &&= has similar behaviour.

···

On Mon, Mar 21, 2011 at 4:09 AM, Paul Sholtz <paul.sholtz@gmail.com> wrote:

I'm looking at some source code, to try and understand it.
There's a variable "weight", and then there's this call:
weight ||= 100
which I take to be equivalent to:
weight = weight || 100
(i.e., performing a logical OR between "weight" and 100).