What is the logic behind this result?

时间:2016-03-24 15:42:01

标签: ruby

def foo(_, _='override')
  _
end

p foo("bye bye")
p foo("hello", "world")

Output:

"override"
"hello"

I could understand if the result was:

"override"
"world"

or even:

"bye bye"
"hello"

But the result I'm getting causes me confusion.

3 个答案:

答案 0 :(得分:4)

如果为其传递参数,则默认参数的计算时间早于常规参数,否则最后会对它们进行求值。几乎肯定但不确定如何证明它。

此示例中的含义:

在时间0拨打p foo("hello", "world")

在时间1 _ = 'override'

时间2 _ = "world"

时间3 _ = "hello"

在打印4个变量时,您会看到“hello”

编辑这里有一些证据:

def foo(_, _='override',_)
  _
end

p foo("bye bye","goodbye")
p foo("hello", "world", "three")

打印

"override"
"three"

答案 1 :(得分:1)

我找不到比这个更好的解释

ruby magic underscore

  

shadowing_lvar_gen中的Ruby解析器中可以找到原因。如果变量名只包含一个下划线,则跳过所有正常的复制检查。

答案 2 :(得分:0)

一种可能的解释是名称_代表"未使用的变量"。你甚至不应该引用它,更不用说期望它的任何价值。由于它是一个特殊名称,它从解析器中获得特殊处理(例如抑制"重复参数"错误)。我想没有人愿意让这段代码产生逻辑结果,因为这些未使用的变量。

如果您将其重命名为其他任何内容(例如a),则会收到错误,因为现在此方法签名没有意义。