I noticed what I find to be a very surprising behavior with the **
(double-splat) operator in Ruby 2.1.1.
When key-value pairs are used before a **hash
, the hash remains unmodified; however, when key-value pairs are only used after the **hash
, the hash is permanently modified.
h = { b: 2 }
{ a: 1, **h } # => { a: 1, b: 2 }
h # => { b: 2 }
{ a: 1, **h, c: 3 } # => { a: 1, b: 2, c: 3 }
h # => { b: 2 }
{ **h, c: 3 } # => { b: 2, c: 3 }
h # => { b: 2, c: 3 }
For comparison, consider the behavior of the single-*
operator on arrays:
a = [2]
[1, *a] # => [1, 2]
a # => [2]
[1, *a, 3] # => [1, 2, 3]
a # => [2]
[*a, 3] # => [2, 3]
a # => [2]
The array remains unchanged throughout.
Do we suppose the sometimes-destructive behavior of **
is intentional, or does it look more like a bug?
In either case, where is the documentation describing how the **
operator is meant to work?
I also asked this question in the Ruby Forum.
UPDATE
The bug is fixed in Ruby 2.1.3+.
The answers to the question seem to be:
It's probably a bug, rather than intentional.
The behavior of the
**
operator is documented very briefly in the core library rdoc.Thanks to the suggestions of several commenters, I've posted the bug to the Ruby trunk issue tracker.
UPDATE:
The bug was fixed in changeset r45724. The comment there was "keyword splat should be non-destructive," which makes this an authoritative answer.
I noticed the diff between 2.1.5 and 2.3.1
Example is an irb method and a way of calling it
In 2.1.5 the following results in retaining value
In 2.3.1 the value is 'b'
I am not sure which it should be?
In 2.3.1 the hash provided as double splat overrides the same key of the first item in a list.