Double Pipe Symbols in Ruby Variable Assignment?
The code foo ||= bar
is almost equivalent to foo = foo || bar
. In Ruby (as in many languages, like JavaScript or Io) boolean operators are "guard" operators. Instead of always returning true
or false
, they evaluate to the value of the first operand that evaluates to a "truthy" value.
For example, this code foo = 1 || delete_all_files_from_my_computer()
will not delete anything: foo will be set to 1
and the second operand won't even be evaluated.
In Ruby, the only "non-truthy" values are nil
and false
. So the code foo ||= bar
will only evaluate bar
and set foo
to the result if foo
is nil
or false
.
As instance variables default to nil
when not set, code like @foo ||= bar
is a common Ruby idiom to set the instance variable if it has not already been set.
You can think of it as short for:
@current_user = @current_user || User.find_by_id(session[:user_id])
@current_user
gets evaluated first, if it is non-null then the OR short-circuits, returning the value of @current_user, and not calling User.find_by_id.
(This works only because Ruby treats null as false, and non-null as true, in a boolean context. It doesn't work for languages like Java that don't treat non-booleans as truthy.)
It's a conditional assignment. From here:
x = find_something() #=>nil
x ||= "default" #=>"default" : value of x will be replaced with "default", but only if x is nil or false
x ||= "other" #=>"default" : value of x is not replaced if it already is other than nil or false