What does ||= (or-equals) mean in Ruby?

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.


a ||= b is a conditional assignment operator. It means:

  • if a is undefined or falsey, then evaluate b and set a to the result.
  • Otherwise (if a is defined and evaluates to truthy), then b 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 to a = a + b
  • a ||= b roughly translates to a || 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

In short, a||=b means: If a is undefined, nil or false, assign b to a. Otherwise, keep a intact.


Concise and complete answer

a ||= b

evaluates the same way as each of the following lines

a || a = b
a ? a : a = b
if a then a else a = b end

-

On the other hand,

a = a || b

evaluates the same way as each of the following lines

a = a ? a : b
if a then a = a else a = b end

-

Edit: As AJedi32 pointed out in the comments, this only holds true if: 1. a is a defined variable. 2. Evaluating a one time and two times does not result in a difference in program or system state.

Tags:

Ruby

Operators