3

最近我开始学习 Ruby,我正在试验 Ruby 如何调用单个对象的方法。但是,下面的代码让我很难受,因为我没有意识到它实际上是如何工作的

a = 4
b = -3
c = 2

puts a*b-c                      # operator precedence preserved
puts a . * b . - c              # operator precedence not preserved
puts a.send(:*, b).send(:-, c)  # operator precedence preserved
puts a-b*c                      # operator precedence preserved
puts a . - b . * c              # operator precedence preserved
puts a.send(:-, b).send(:*, c)  # operator precedence not preserved

输出:

-14
-20    
-14
10
10
14

谁能解释运算符优先级如何在这里工作?我假设每个部分中的所有三种语法都应该反映相同的含义。如果这个问题已经被问过或解释过,我首先道歉。

4

2 回答 2

5

运算符优先级仅在使用运算符时适用。所有这些例子:

puts a . * b . - c              # operator precedence not preserved
puts a.send(:*, b).send(:-, c)  # operator precedence preserved
puts a . - b . * c              # operator precedence preserved
puts a.send(:-, b).send(:*, c)  # operator precedence not preserved

是直接的方法调用,与相应的运算符相比,它们的顺序要么错误,要么正确。

也许括号使它更清楚?

puts a.*(b.-(c))                # .- called first, .* with the return value of .-
puts a.send(:*, b).send(:-, c)  # .* called first, .- with the return value of .*
puts a.-(b.*(c))                # .* called first, .- with the return value of .*
puts a.send(:-, b).send(:*, c)  # .- called first, .* with the return value of .-
于 2012-08-07T02:53:27.340 回答
0

只有示例 1 和 4 遵循算术运算符优先级,因为只有示例 1 和 4 将运算符称为运算符。

示例 3 和 6 都调用了该send方法,因此它们的行为与任何其他方法调用一样。它们是从左到右的,就像你在一组数据上写一个复杂的单行代码时发生的那样,就像这样:

somearray.select{|x| somecondition(x)}.map{|x| somefunction(x)}.each{|x| puts x}

唯一令人困惑的是示例 2 和 5。这些技巧是,如果删除句点周围的空格,您可以理解发生了什么。然后你得到:

puts a.* b.- c
puts a.- b.* c

现在,很明显,首先在 b 上调用了一个方法,应用了一些将 c 作为参数的运算符。这会返回一些结果。该结果用作对 a 的运算符调用的参数。结果被赋予puts。换句话说,这些行从右到左求值,语句等价于

puts(a.*(b.-(c)))
puts(a.-(b.*(c)))
于 2012-08-07T02:51:13.473 回答