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

牧云@^-^@ 提交于 2019-11-27 02:04:40

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:

  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 

From Programming Ruby 1.9:

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

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

Mondher Gatri

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

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