双splat运算符破坏性地修改哈希 - 这是一个Ruby bug吗?

use*_*951 10 ruby syntax hash splat double-splat

我注意到我发现**Ruby 2.1.1中的(双splat)运算符是一个非常令人惊讶的行为.

当在a之前使用键值对时**hash,哈希保持不变; 但是,当键值对仅在之后使用时**hash,哈希值将被永久修改.

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 }
Run Code Online (Sandbox Code Playgroud)

为了进行比较,请考虑单个*运算符在数组上的行为:

a = [2]

[1, *a]     # => [1, 2]
a           # => [2]

[1, *a, 3]  # => [1, 2, 3]
a           # => [2]

[*a, 3]     # => [2, 3]
a           # => [2]
Run Code Online (Sandbox Code Playgroud)

阵列始终保持不变.


我们是否认为有时破坏性的行为**是有意的,还是看起来更像是一个错误?

在任何一种情况下,文档描述了**操作符的工作方式在哪里?


我也在Ruby论坛中问了这个问题.

UPDATE

该错误已在Ruby 2.1.3+中修复.

use*_*951 7

这个问题的答案似乎是:

  1. 这可能是一个错误,而不是故意的.

  2. **核心库rdoc中非常简要地记录了操作符的行为.

感谢几位评论者的建议,我已将错误发布到Ruby trunk问题跟踪器.


更新:

该错误已在changeset r45724中修复.那里的评论是" 关键字splat应该是非破坏性的 ",这使得这是一个权威的答案.