Bug #16371
closedInconsistent usage of Double splat operator
Description
Here is an issue with a weird behavior of ruby double splat operator:
a = {a: 'a'}
b = {'b' => 'b'}
{x: 'x', **a}
#=> {:x=>"x", :a=>"a"}
{x: 'x', **b}
#=> TypeError (hash key "b" is not a Symbol)
When I do that implicitly, it works:
{x: 'x', **{'b' => 'b'}}
#=> {:x=>"x", "b"=>"b"}
At the same time:
{**{'b' => 'b'}}
# TypeError (hash key "b" is not a Symbol)
From my point of view, it definitely works inconsistently.
Could you help with this example or give an advice? (maybe I used it incorrectly?)
Updated by mame (Yusuke Endoh) over 5 years ago
**
operator is for keyword arguments, and in Ruby 2.6, non-symbol key is not allowed in keyword arguments. So in principle, {x: 'x', **{'b' => 'b'}}
should raise an exception.
Because of the spec change of keyword arguments (#14183), non-symbol key is allowed in Ruby 2.7, and all shown cases work without exception.
Do you want the case to raise an exception in Ruby 2.6?
Updated by matz (Yukihiro Matsumoto) over 5 years ago
I think this inconsistency is a bug. Double splat in hash expressions needs to work as interpolation.
Matz.
Updated by mame (Yusuke Endoh) over 5 years ago
matz, the following is the current behaviors. Do you mean which should be fixed?
(1) 2.7, via variable
b = {"b" => "b"}; p({x: "x", **b}) #=> current behavior: {:x=>"x", "b"=>"b"}
(2) 2.6, via variable
b = {"b" => "b"}; p({x: "x", **b}) #=> current behavior: hash key "b" is not a Symbol (TypeError)
(3) 2.7, with literal
p({x: "x", **{"b" => "b"}}) #=> current behavior: {:x=>"x", "b"=>"b"}
(4) 2.6, with literal
p({x: "x", **{"b" => "b"}}) #=> current behavior: {:x=>"x", "b"=>"b"}
Updated by jeremyevans0 (Jeremy Evans) about 4 years ago
- Status changed from Open to Closed
Ruby 2.6 is now in security maintenance mode, so behavior of the double splat operator will not be changed in it.