Given this method definition:
def foo(a = nil, b: nil)
p a: a, b: b
end
When I invoke the method with a single hash argument, the hash is always implicitly converted to keyword arguments, regardless of **
:
hash = {b: 1}
foo(hash) #=> {:a=>nil, :b=>1}
foo(**hash) #=> {:a=>nil, :b=>1}
I can pass another (empty) hash as a workaround:
foo(hash, {}) #=> {:a=>{:b=>1}, :b=>nil}
But, this looks pretty cumbersome and awkward.
I would have expected Ruby to handle this more like arrays are handled, i.e.:
foo(hash) #=> {:a=>{:b=>1}, :b=>nil}
foo(**hash) #=> {:a=>nil, :b=>1}
And using literals:
foo({b: 1}) #=> {:a=>{:b=>1}, :b=>nil}
foo(b: 1) #=> {:a=>nil, :b=>1}
foo(**{b: 1}) #=> {:a=>nil, :b=>1}
The current implementation looks like a flaw and the way I was expecting it to work seems obvious.
Is this an overlooked edge case? I don't think so. There's probably a good reason that it wasn't implemented this way.
Can someone enlighten me, please?