I can't understand precedence of Ruby operators in a following example:
x = 1 && y = 2
Since &&
has higher precedence than =
, my understanding is that similarly to +
and *
operators:
1 + 2 * 3 + 4
which is resolved as
1 + (2 * 3) + 4
it should be equal to:
x = (1 && y) = 2
However, all Ruby sources (including internal syntax parser Ripper
) parse this as
x = (1 && (y = 2))
Why?
EDIT [08.01.2016]
Let's focus on a subexpression: 1 && y = 2
According to precedence rules, we should try to parse it as:
(1 && y) = 2
which doesn't make sense because =
requires a specific LHS (variable, constant, []
array item etc). But since (1 && y)
is a correct expression, how should the parser deal with it?
I've tried consulting with Ruby's parse.y
, but it's so spaghetti-like that I can't understand specific rules for assignment.
Simple. Ruby only interprets it in a way that makes sense. =
is assignment. In your expectation:
x = (1 && y) = 2
it does not make sense to assign something to 1 && y
. You can only assign something to a variable or a constant.
And note that the purpose of the precedence rule is to disambiguate an otherwise ambiguous expression. If one way to interpret it does not make sense, then there is no need for disambiguation, and hence the precedence rule would not be in effect.
My understanding is that in the case of
x = 1 && y = 2
The logical AND is parsed first. The AND then is forced to evaluate its left side and its right side. In the evaluation the left side the first assignment occurs, and then in the evaluation of the right side the second does the same. It is for this reason that in the case of:
x = false && y = 2
"y" will never be assigned. The AND is hit, forcing the x assignment to evaluate, but never bothering to run the y assignment, as it is unnecessary for the AND to fulfill its purpose.
In other words, the parser is, again, simply to my understanding, smart enough to recognize that in running the AND the equation is split into a left and right side (equations), which are in turn evaluated according to the order of operation.