![](/img/trans.png)
[英]What is the point of using Ruby's double-splat (`**`) in method calls?
[英]Double-splat operator destructively modifies hash – is this a Ruby bug?
我注意到使用Ruby 2.1.1中的**
(双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]
整个数组保持不变。
我们是否认为**
有时具有破坏性的行为是故意的,还是更像是一个bug?
在这两种情况下,说明**
运算符如何工作的文档在哪里?
我也在Ruby论坛中问了这个问题。
更新
该错误已在Ruby 2.1.3+中修复。
该问题的答案似乎是:
这可能是一个错误,而不是故意的。
核心库rdoc中非常简短地记录了**
运算符的行为。
感谢几个评论者的建议,我将该错误发布到了Ruby trunk问题跟踪器 。
更新:
该错误已在变更集r45724中修复 。 那里的评论是“ 关键字splat应该是非破坏性的 ”,这使它成为权威的答案。
我注意到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中,值为“ b”
(irb):2: warning: duplicated key at line 2 ignored: :a
=> {:a=>"b"}
我不确定应该是哪个?
在2.3.1中,作为double splat提供的哈希值会覆盖列表中第一项的相同键。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.