I have a question regarding the and/&&/= keywords in Ruby.
The ruby docs say that the precedence for the mentioned keywords is: (1)&&, (2)=, (3)and.
I have this snippet of code I wrote:
def f(n)
n
end
if a = f(2) and b = f(4) then
puts "1) #{a} #{b}"
end
if a = f(2) && b = f(4) then
puts "2) #{a} #{b}"
end
The output is:
1) 2 4 [Expected]
2) 4 4 [Why?]
For some reason using the && causes both a and b to evaluate to 4?
Operator Precedence ¶ The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression 1 + 5 * 3 , the answer is 16 and not 18 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator.
The logical-AND operator ( && ) has higher precedence than the logical-OR operator ( || ), so q && r is grouped as an operand. Since the logical operators guarantee evaluation of operands from left to right, q && r is evaluated before s-- .
The order of precedence is: logical complements ( not ) are performed first, logical conjunctions ( and ) are performed next, and logical disjunctions ( or ) are performed at the end. Notice: You can always use parentheses to change the default precedence.
I don't quite understand the question you are asking. I mean, you have already given the answer yourself, before even asking the question: &&
binds tighter than =
while and
binds less tightly than =
.
So, in the first case, the expression is evaluated as follows:
( a=f(2) ) and ( b=f(4) )
( a= 2 ) and ( b=f(4) )
2 and ( b=f(4) ) # a=2
2 and ( b= 4 ) # a=2
2 and 4 # a=2; b=4
4 # a=2; b=4
In the second case, the evaluation is as follows:
a = ( f(2) && ( b=f(4) ) )
a = ( 2 && ( b=f(4) ) )
a = ( 2 && ( b= 4 ) )
a = ( 2 && 4 ) # b=4
a = 4 # b=4
4 # b=4; a=4
The reason is simple: precedence. As you say, the order is:
Since &&
has precedence over =
, the statement is evaluated like this:
if a = (f(2) && (b = f(4))) then
Which results in:
if a = (2 && 4) then
When x
and y
are integers, x && y
returns y
. Thus 2 && 4
results in a = 4
.
For comparison's sake, the first one is evaluated like this:
if (a = f(2)) and (b = f(4)) then
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With