2015-08-14 35 views
0

我发现this question下这段代码,如果任何参数传递给方法,该方法检查:可选参数语法

def foo(bar = (bar_set = true; :baz)) 
    if bar_set 
    # optional argument was supplied 
    end 
end 

什么; :baz在此默认值的目的,并在我会用什么样的情况下它?

+0

编写代码打印'bar'(也可能是'bar_set'),然后用零参数调用'foo',然后用一个调用。 – cremno

+0

非常有教育意义,谢谢。 – npresco

回答

1

想法是,只有当值不传递给参数bar时,才会评估= (bar_set = true; :baz)

在Ruby中,多个连续表达式的返回值是最后一个表达式的值。因此,= (bar_set = true; :baz)将值true指定为bar_set,然后将:baz设置为bar的值(因为括号中的代码将计算为:baz,它是最后一个表达式)。

如果参数通过了,bar_set将是nil并且bar的值将是任何给出的值。

+0

非常感谢! – npresco

+0

这是必要的,因为无论您用作默认值的值是否也可以由调用者传递,所以通过查看值是否通过参数是不可能的。但是一种方法可能想知道这一点。例如,如果你有一个允许非常快的折叠的自定义集合,你可能想重写'Enumerable#inject',但是它的契约非常复杂,它基本上有4个“重载”。这对于YARV,JRuby和co来说并不是问题,因为它们使用C或Java实现,因此可以有权访问VM,但在Ruby中,您需要这样的技巧。 –

+0

:-D我刚刚注意到启发这个问题的答案是我的:-D –