10

**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 Forumでもこの質問をしました。

アップデート

このバグは Ruby 2.1.3+ で修正されています。

4

2 に答える 2

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 では、値は「b」です。

(irb):2: warning: duplicated key at line 2 ignored: :a
=> {:a=>"b"}

私はそれがどれであるべきか分かりませんか?

2.3.1 では、ダブル スプラットとして提供されるハッシュは、リストの最初の項目の同じキーをオーバーライドします。

于 2016-07-27T18:05:30.707 に答える