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