繁体   English   中英

Double-splat运算符破坏性地修改了哈希-这是Ruby错误吗?

[英]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+中修复。

该问题的答案似乎是:

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

  2. 核心库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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM