鉴于此方法定义:
def foo(a = nil, b: nil)
p a: 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}
当前的实现看起来像一个缺陷,我期待它工作的方式似乎是显而易见的.
这是一个被忽视的边缘案例吗?我不这么认为.可能有一个很好的理由是它没有以这种方式实现.
有人可以开导我吗?
最佳答案 >至于缺乏**部分:
我的猜测是,为了使方法调用变得简单,Ruby总是一次解释key:value form而不用括号作为带有省略括号的哈希,无论它实际上是否会被解释为这样的哈希或关键字参数.
然后,为了将其解释为关键字参数,**隐式应用于它.
因此,如果您已经传递了显式哈希,它将不会对上面的过程产生影响,并且有空间将其解释为实际哈希或关键字参数.
当你明确地传递**时会发生什么:
method(**{key: value})
哈希是分解的:
method(key: value)
然后被解释为带有省略大括号的哈希:
method({key: value})
然后被解释为哈希或关键字参数.
>对于优先于其他参数的关键字参数,请参阅Ruby core:https://bugs.ruby-lang.org/issues/11967上的这篇文章.