参见英文答案 > Keyword arguments unpacking (splat) in Ruby 3个
这个想法类似于你在python中使用装饰器所做的,我不知道该方法采用了什么参数,所以我传递* args,** kwargs作为一般情况
当我想将空哈希作为kwargs传递给不带参数的方法时,问题就出现了
def my_method
'I have run correctly'
end
args = []
kwargs = {}
my_method *args, **kwargs
=> ArgumentError: wrong number of arguments (given 1, expected 0)
有趣的是,只有kwargs变量似乎是问题,因为:
my_method *args, **{}
=> 'I have run correctly'
如果你可以建议一种方法将方法对象实际作为参数传递给函数,那也是完美的.
最佳答案 如果不在方法定义中声明它,则不能将任意数量的参数传递给ruby方法.传递* args是有效的,因为* args是空的,它基本上好像你没有传递方法的参数,这就是my_method所期望的.对于kwargs,您将空哈希作为参数传递.由于声明该方法不带参数,因此会引发错误.
一般来说,在ruby中执行此操作的方法是这样的:
def my_method(*args, **kwargs)
'I have run correctly'
end
如果ruby方法可以接受无限数量的参数或关键字参数,则需要在方法的定义中明确.
然而,更频繁地,你会看到这样的习语:
def my_method(arg, opts={})
# do something
end
# Invoke the method like this:
# args == ['argument', 'another argument']
# opts == {opt1: 'val1', opt2: 'val2'}
my_method('some argument', opt1: 'val1', opt2: 'val2')
关于你对my_method * args的观察,** kwargs的行为与my_method * args不同,** {} ……我首先要说的是,如果你的动机首先是关于学习Ruby,那么我会再次强调我的上述观点kwargs不是Ruby中常用的,至少不像Python中使用的那样.
之后我会说这很奇怪.
我注意到:
[**kwargs] # => [{}]
[**{}] # => []
# And even more interesting:
[**{}.itself] # => [{}]
所以我说**对于kwargs,解释器抱怨是因为你将空哈希传递给一个不期望任何参数的方法.但至于为何与** {}不同,我不确定.我现在正在挖掘,但我当前的怀疑是老实说,这是翻译的侥幸.没有理由将这些评估为不同,因为将两者分配给一个变量……
更重要的是,双splat运算符的采用并不是非常普遍,主要是因为偏爱上面描述的opts = {}成语.这也不是许多人在实践中遇到的用例.程序员必须显式地将空哈希传递给这样一个方法,当它们可以(无论是kwargs还是opts)只是省略了参数.所以是的…我认为这可能是翻译的侥幸.