What does ||= (or-equals) mean in Ruby?
What does the following code mean in Ruby?
||=
Does it have any meaning or reason for the syntax?
a ||= b
is a conditional assignment operator. It means:
- if
a
is undefined or falsey, then evaluateb
and seta
to the result. - Otherwise (if
a
is defined and evaluates to truthy), thenb
is not evaluated, and no assignment takes place.
For example:
a ||= nil # => nil
a ||= 0 # => 0
a ||= 2 # => 0
foo = false # => false
foo ||= true # => true
foo ||= false # => true
Confusingly, it looks similar to other assignment operators (such as +=
), but behaves differently.
-
a += b
translates toa = a + b
-
a ||= b
roughly translates toa || a = b
It is a near-shorthand for a || a = b
. The difference is that, when a
is undefined, a || a = b
would raise NameError
, whereas a ||= b
sets a
to b
. This distinction is unimportant if a
and b
are both local variables, but is significant if either is a getter/setter method of a class.
Further reading:
- http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html
This question has been discussed so often on the Ruby mailing-lists and Ruby blogs that there are now even threads on the Ruby mailing-list whose only purpose is to collect links to all the other threads on the Ruby mailing-list that discuss this issue.
Here's one: The definitive list of ||= (OR Equal) threads and pages
If you really want to know what is going on, take a look at Section 11.4.2.3 "Abbreviated assignments" of the Ruby Language Draft Specification.
As a first approximation,
a ||= b
is equivalent to
a || a = b
and not equivalent to
a = a || b
However, that is only a first approximation, especially if a
is undefined. The semantics also differ depending on whether it is a simple variable assignment, a method assignment or an indexing assignment:
a ||= b
a.c ||= b
a[c] ||= b
are all treated differently.