Ruby on Rails Tutorial: Learn Web Development with Rails (Addison-Wesley Professional Ruby Series) by Michael Hartl

Ruby on Rails Tutorial: Learn Web Development with Rails (Addison-Wesley Professional Ruby Series) by Michael Hartl

Author:Michael Hartl
Language: eng
Format: epub
Publisher: Pearson Education
Published: 2016-11-17T00:00:00+00:00


* * *

Box 8.1: What the *$@! is ||= ?

The ||= (“or equals”) assignment operator is a common Ruby idiom and is thus important for aspiring Rails developers to recognize. Although at first it may seem mysterious, or equals is easy to understand by analogy.

We start by noting the common pattern of incrementing a variable:

x = x + 1

Many languages provide a syntactic shortcut for this operation; in Ruby (and in C, C++, Perl, Python, Java, etc.), it can also appear as follows:

x += 1

Analogous constructs exist for other operators as well:

$ rails console

>> x = 1

=> 1

>> x += 1

=> 2

>> x *= 3

=> 6

>> x -= 8

=> -2

>> x /= 2

=> -1

In each case, the pattern is that x = x O y and x O= y are equivalent for any operator O.

Another common Ruby pattern is assigning to a variable if it’s nil but otherwise leaving it alone. Recalling the or operator || seen in Section 4.2.3, we can write this as follows:

>> @foo

=> nil

>> @foo = @foo || "bar"

=> "bar"

>> @foo = @foo || "baz"

=> "bar"

Since nil is false in a boolean context, the first assignment to @foo is nil || "bar", which evaluates to "bar". Similarly, the second assignment is @foo || "baz", i.e., "bar" || "baz", which also evaluates to "bar". This is because anything other than nil or false is true in a boolean context, and the series of || expressions terminates after the first true expression is evaluated. (This practice of evaluating || expressions from left to right and stopping on the first true value is known as short-circuit evaluation. The same principle applies to && statements, except in this case evaluation stops on the first false value.)

Comparing the console sessions for the various operators, we see that @foo = @foo || "bar" follows the x = x O y pattern with || in the place of O:

x = x + 1 -> x += 1

x = x * 3 -> x *= 3

x = x - 8 -> x -= 8

x = x / 2 -> x /= 2

@foo = @foo || "bar" -> @foo ||= "bar"

Thus we see that @foo = @foo || "bar" and @foo ||= "bar" are equivalent. In the context of the current user, this suggests the following construction:

@current_user ||= User.find_by(id: session[:user_id])

Voilà!

(Technically, Ruby evaluates the expression @foo || @foo = "bar", which avoids an unnecessary assignment when @foo is nil or false. But this expression doesn’t explain the ||= notation as well, so the above discussion uses the nearly equivalent @foo = @foo || "bar".)



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.