Operator precedence for And/&& in Ruby [duplicate]

大兔子大兔子 提交于 2019-11-26 09:53:35

问题


This question already has an answer here:

  • Difference between “and” and && in Ruby? 7 answers

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?


回答1:


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



回答2:


The reason is simple: precedence. As you say, the order is:

  1. &&
  2. =
  3. and

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 



回答3:


From Programming Ruby 1.9:

The only difference in the two forms is precedence (and binds lower than &&).




回答4:


I do not know the specific rules that can help in this situation, but let's use the priorities of operations. Using the rules of priorities, we can divide the computation of the second expression on several steps

1 f(2) &&  b => expr1
2 expr1 = f(4) => expr2
3 a = expr2

Obvious that in Step 2 we get an incorrect situation - on the left side of = is rvalue - temporary object, which can not be assigning by any value. I assume that syntactic analyzer break the rules of priority evaluation of expressions when encounter such situations. More details on the calculations of expressions can be found here




回答5:


if you modify your code like this you will get what you expect

def f(n) 
  n
end

if (a = f(2) and  b = f(4)) then  
  puts "1) #{a} #{b}" 
end

if (a = f(2)  and  b = f(4)) then   
  puts "2) #{a} #{b}"         
end

1) 2 4

2) 2 4



来源:https://stackoverflow.com/questions/1840488/operator-precedence-for-and-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!