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

jed*_*iah 5 ruby argument-passing

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

def woot(a = nil, b: nil)
  ...
end
Run Code Online (Sandbox Code Playgroud)

Hash实例传递给awhen 的最简单方法b是什么?

我试过了

woot(x: 1)
woot({x: 1})
h = {x: 1}
woot(h)
Run Code Online (Sandbox Code Playgroud)

但他们都提高了

ArgumentError: unknown keyword: x
Run Code Online (Sandbox Code Playgroud)

打电话的唯一方法是我弄清楚了

woot({x: 1}, **{})
Run Code Online (Sandbox Code Playgroud)

有更好的方法吗?

Kar*_*ath 1

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

我认为没有更好的解决方法,尽管这有点短(但不一定更干净):

woot({x: 1}, {})
Run Code Online (Sandbox Code Playgroud)

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


(*):嗯,并不总是:woot({1=>3})很乐意将哈希值传递给第一个可选参数。

更奇怪的是,在 的情况下woot({1=> 5, :b => 4}),Ruby 会拆分字典,并传递{1=>5}给第一个可选参数。

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

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