Double-splat operator destructively modifies hash – is this a Ruby bug?

青春壹個敷衍的年華 提交于 2019-11-27 04:41:48

问题


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+.


回答1:


The answers to the question seem to be:

  1. It's probably a bug, rather than intentional.

  2. 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.




回答2:


I noticed the diff between 2.1.5 and 2.3.1

Example is an irb method and a way of calling it

$ irb
>> def foo(opts) opts end
=> :foo
>> foo a: 'a', ** {a: 'b'}

In 2.1.5 the following results in retaining value

=> {:a=>"a"}

In 2.3.1 the value is 'b'

(irb):2: warning: duplicated key at line 2 ignored: :a
=> {:a=>"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.



来源:https://stackoverflow.com/questions/23282342/double-splat-operator-destructively-modifies-hash-is-this-a-ruby-bug

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!