我注意到我发现在Ruby 2.1.1中使用**
(double-splat)运算符是一个非常令人惊讶的行为。
在**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 }
为了进行比较,请考虑单个 - *
运算符在数组上的行为:
a = [2]
[1, *a] # => [1, 2]
a # => [2]
[1, *a, 3] # => [1, 2, 3]
a # => [2]
[*a, 3] # => [2, 3]
a # => [2]
阵列始终保持不变。
我们是否认为**
的有时破坏性行为是有意的,还是看起来更像是一个错误?
在任何一种情况下,描述**
运算符的工作方式的文档在哪里?
我也问了这个问题in the Ruby Forum。
更新
该错误已在Ruby 2.1.3 +中修复。
答案 0 :(得分:7)
问题的答案似乎是:
这可能是一个错误,而不是故意的。
core library rdoc中非常简要地记录了**
运算符的行为。
感谢几位评论者的建议,我已将错误发布到Ruby trunk issue tracker。
<强>更新强>
该错误已在changeset r45724中修复。那里的评论是“关键字splat应该是非破坏性的”,这使得这是一个权威的答案。
答案 1 :(得分:1)
我注意到2.1.5和2.3.1之间的差异
示例是irb方法和调用它的方法
$ irb
>> def foo(opts) opts end
=> :foo
>> foo a: 'a', ** {a: 'b'}
在2.1.5中,以下结果为保留值
=> {:a=>"a"}
在2.3.1中,值为&#39; b&#39;
(irb):2: warning: duplicated key at line 2 ignored: :a
=> {:a=>"b"}
我不确定它应该是什么?
在2.3.1中,以double splat提供的哈希覆盖列表中第一项的相同键。