2

我是 Ruby 的新手,我完全反感。为什么下面的代码:

def some_method(v=1) 10*v end

puts (some_method (1).next)
puts  some_method (1).next

评估为:

20
11
4

3 回答 3

5

在 Ruby 1.8.7 中,第一个示例的计算结果为 20,因为这是正确的行为。

让我们分解一下。我们从

puts (some_method (1).next)

然后我们添加缺失/隐式括号:

puts((some_method((1).next)))

让我们把它分成几个不同的部分:

puts(
  (
    some_method(
      (1).next
    )
  )
)

Ruby 从内部开始,评估(1). 那的价值是,嗯1,,所以我们得到

puts(
  (
    some_method(
      1.next
    )
  )
)

接下来,1.next,它返回2

puts(
  (
    some_method(
      2
    )
  )
)

因此,Ruby2作为参数传递给some_method,然后乘以 10 并返回正确的值20

puts(
  (
    20
  )
)

这 - 不出所料的输出20

你可能想写的是

puts some_method(1).next

哪个输出11。您在方法名称和括号之间添加的空格很重要。

有趣的是,如果您确实在运行 1.8.7,您实际上会在最后一个示例中收到警告:

>> puts some_method (1).next
(irb):13: warning: don't put space before argument parentheses
11
=> nil
于 2013-09-17T11:22:02.513 回答
1

在 ruby​​ 1.8 兼容模式下的 jruby-1.6.7.2 下,我看到:

20
11

而在 1.9 兼容模式下,我看到

20
20

我怀疑优先运算符发生了变化。

于 2013-09-17T11:25:36.913 回答
1
# first case
puts (some_method (1).next)

=> 通过 some_method (1).next 周围的 () 将所有内容包装到 puts 中。

some_method (1).next => (1).next => 2 => 2*10 => 20

# second case
puts some_method (1).next

=> 这里没有围绕puts的“包装器”

some_method (1).next => 1*10 => 10 => 10.next => 11

更新:(红宝石 1.9.2-p290)

“有空间”和“没有空间”之间有趣的区别(好吧,这没有答案,我认为这是另一个问题:))

irb(main):011:0> puts some_method (1).next
20
=> nil
irb(main):012:0> puts some_method(1).next
11
=> nil
于 2013-09-17T10:57:52.747 回答