为什么在“splatting”关键字参数时**是可选的?

鉴于此方法定义:

def foo(a = nil, b: nil) pa: a, b: b end 

当我使用单个哈希参数调用方法时,无论**如何,哈希都会隐式转换为关键字参数:

 hash = {b: 1} foo(hash) #=> {:a=>nil, :b=>1} foo(**hash) #=> {:a=>nil, :b=>1} 

我可以传递另一个(空)哈希作为变通方法:

 foo(hash, {}) #=> {:a=>{:b=>1}, :b=>nil} 

但是 ,这看起来非常麻烦和笨拙。

我本以为Ruby会处理这个更像是处理数组,即:

 foo(hash) #=> {:a=>{:b=>1}, :b=>nil} foo(**hash) #=> {:a=>nil, :b=>1} 

并使用文字:

 foo({b: 1}) #=> {:a=>{:b=>1}, :b=>nil} foo(b: 1) #=> {:a=>nil, :b=>1} foo(**{b: 1}) #=> {:a=>nil, :b=>1} 

当前的实现看起来像一个缺陷,我期待它工作的方式似乎是显而易见的。

这是一个被忽视的边缘案例吗? 我不这么认为。 可能有一个很好的理由是它没有以这种方式实现。

请有人开导我吗?

  1. 至于缺乏**部分:

    我的猜测是,为了使方法调用变得简单,Ruby总是一次解释key: value form而不用括号作为带有省略括号的哈希,无论它实际上是否会被解释为这样的哈希或关键字参数。

    然后,为了将其解释为关键字参数, **隐式应用于它。

    因此,如果您已经传递了显式哈希,它将不会对上面的过程产生影响,并且有空间将其解释为实际哈希或关键字参数。

    当你明确地传递**时会发生什么:

     method(**{key: value}) 

    哈希是分解的:

     method(key: value) 

    然后被解释为带有省略括号的哈希:

     method({key: value}) 

    然后被解释为哈希或关键字参数。

  2. 至于优先于其他参数的关键字参数,请参阅Ruby核心上的这篇文章: https : //bugs.ruby-lang.org/issues/11967 。