zeacuss
zeacuss

Reputation: 2623

Does the || operator evaluate the second argument even if the first argument is true?

I'm trying to evaluate the expression (a=10) || (rr=20) while the rr variable is not defined

so typing rr in the ruby console before evaluating the previous expression returns

rr
NameError: undefined local variable or method `rr' for main:Object
from (irb):1
from :0

When I write the expression (a=10) || (rr=20) it returns 10, and when I write rr afterwards it says nil

(a=10) || (rr=20)
rr  # => nil

so, why is this happening? Shouldn't rr be defined only if the second argument of the || operator is evaluated, which should be never based on the documentation?

Upvotes: 10

Views: 3115

Answers (4)

Aliaksei Kliuchnikau
Aliaksei Kliuchnikau

Reputation: 13719

This happens because the ruby interpreter defines a variable when it sees an assignment to it (but before it executes the actual line of code). You can read more about it in this answer.

Boolean OR (||) expression will evaluate to the value of left hand expression if it is not nil and not false, else || will evaluate to the value of right hand expression.

In your example the ruby interpreter sees an assignment to a and rr (but it doesn't execute this line yet), and initializes (defines, creates) a and rr with nil. Then it executes the || expression. In this || expression, a is assigned to 10 and 10 is returned. r=20 is not evaluated, and rr is not changed (it is still nil). This is why in the next line rr is nil.

Upvotes: 12

nkm
nkm

Reputation: 5914

As @DOC said, && and || are known as short circuited conditional operators.

In case of ||, if the left part of || expression returns true, the right part won't be executed. That means the right part will be executed only if the left part of || expression returns false.

In case of &&, right part of the&&expression will be executed only if left part of && returns true.

In the given scenario (a=10) || (rr=20), rr=20 won't be executed since the ruby expression a=10 returns true. Note that in ruby assignment expression returns true except nil and false.

Upvotes: 5

tadman
tadman

Reputation: 211580

When the parser discovers a variable it is automatically valid within the context it's defined in. Evaluating rr on its own is not valid. Evaluating rr=20 is sufficient to cause a definition even if the value assignment never occurs.

This is a quirk of how Ruby tries to discern between variables and method calls. It's imperfect but usually works out for the best.

Upvotes: 2

DGM
DGM

Reputation: 26979

I think variable definement happens at the parsing stage, not the execution moment. So when it evaluates the line, it parses the whole thing and the variable is defined, but unassigned.

Upvotes: 3

Related Questions