这个Ruby方法调用最终可以不用** {}吗?

时间:2015-01-18 05:25:53

标签: ruby argument-passing

我有一个像这样定义的方法:

def woot(a = nil, b: nil)
  ...
end

省略Hash时,将a个实例传递给b的最简单方法是什么?

我试过

woot(x: 1)
woot({x: 1})
h = {x: 1}
woot(h)

但他们都提出

ArgumentError: unknown keyword: x

进行我已经想到的通话的唯一方法是

woot({x: 1}, **{})

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

您的第一个参数是可选的,因此Ruby假定您传递的哈希是针对命名参数(*)。

我认为没有更好的解决方法,虽然这有点短(但不一定更清洁):

woot({x: 1}, {})

如果我是你,我会更改方法签名以解决歧义。


(*):好吧,并非总是如此:woot({1=>3})会愉快地将哈希值传递给第一个可选参数。

即使更奇怪,如果是woot({1=> 5, :b => 4}),Ruby会拆分字典,并将{1=>5}传递给第一个可选参数。

看起来首先尝试抓取命名参数(并且会抱怨不存在的名称),然后将其余参数传递给可选参数。

但我很乐意看到一些语言律师的解释......

答案 1 :(得分:0)

如果您不希望b的默认值发生变化,永远,那么明确传递它会怎么样?

woot({x: 1}, b: nil)

当然,如果b的默认值确实改变了一天,那么您仍然会传递nil,从而覆盖{ {1}}该调用的值不是新的默认值。