我发现在 Ruby 2.1.1 中,**
(双星号)操作符的行为非常令人惊讶。
当键值对在 **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]
整个过程中,该数组保持不变。
我们认为**
有时具有破坏性的行为是故意的,还是看起来更像一个错误?
无论哪种情况,哪里有描述**
运算符应如何工作的文档?
我也在Ruby论坛上问过这个问题。
更新
该漏洞已在Ruby 2.1.3+中修复。
h
和i
并执行{**h, **i, d: 5}
时,只有h
被修改,而不是i
。 - sawah
是同一个对象,但这还不是全部。考虑h = { a: 1 }; { **h, a: 99, **h }
。由于最终结果是{ a: 99 }
,因此我们可以看到,即使在达到最终的**h
时,h[:a]
已经被覆盖了。 - user513951