On Mon, Mar 21, 2011 at 4:09 AM, Paul S. [email protected]
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).
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 its 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 doesnt 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.