Ruby 如何将双splat参数折叠为零?

Ruby 如何将双splat参数折叠为零?,ruby,syntax,Ruby,Syntax,Splat在方法调用中扩展空数组可以有效地将参数减少为零(为清晰起见,添加了空括号): 但这不适用于散列参数: def baz() end def qux(**opts) baz(**opts) end qux # ArgumentError, **opts becomes {} 我可以通过显式检查空哈希来解决此问题: def quux(callable, **opts) if opts.empty? callable.() else callable.(**o

Splat在方法调用中扩展空数组可以有效地将参数减少为零(为清晰起见,添加了空括号):

但这不适用于散列参数:

def baz()
end

def qux(**opts)
  baz(**opts)
end

qux # ArgumentError, **opts becomes {}
我可以通过显式检查空哈希来解决此问题:

def quux(callable, **opts)
  if opts.empty?
    callable.()
  else
    callable.(**opts)
  end
end

c = ->{}
quux(c) # works
但是有没有更好的方法来做到这一点,或者是否计划对这种行为进行改变?在编写
bar
qux
时,我不知道
foo
baz
的签名,因为后者是类似于工厂的构造函数包装的一部分。

请尝试以下方法:

def baz()
end

def qux(**opts)
    baz(*opts)
end

qux
h = {}
puts h # {}
puts *h # nothing output 
puts **h #{}
要进一步了解*hash的工作原理,请尝试以下操作:

def baz()
end

def qux(**opts)
    baz(*opts)
end

qux
h = {}
puts h # {}
puts *h # nothing output 
puts **h #{}

为什么需要使用
**opts
*args
也应该使用关键字参数。我想得越久,就越觉得这实际上可能是Ruby中的一个bug。如果
foo(*[])
起作用,那么
baz(**{})
也应该起作用。@PatrickOscity使用args很好。不知怎么忘了。今天我学习了double-splat语法,可能对使用它有点一心一意。简单地使用
*args
适用于我刚才尝试的每种情况,包括可选、可选关键字和必需关键字参数的混合。所以我现在不需要这个。但我仍然同意你的第二个评论,我认为这是不直观的,可能是无意的。我会在bug追踪器上查找并提交一份报告。我认为你的直觉是错误的。您希望
opts
hash扩展到什么?数组splat运算符
*
可以1:1将
数组
元素转换为纯参数列表,对于
哈希
而言,这是不可能的,也是不含糊的。散列的“扩展”需要一个容器对象。试着
{key:123,**opts}
[:key,123,**opts]
看看我的意思。@DavidUnric我明白你的意思,但随着关键字参数的引入,我认为我的直觉至少和你的一样合理:
*[]
扩展为零位参数,所以
**{}
应展开为零个命名参数。可以说,这取决于您的观点,但在方法调用的上下文中,有理由让它按照我预期的方式工作。