0

この動作は正しいですか? 次のようなコードを実行しています。

@a_hash = {:a => 1}
x = @a_hash
x.merge!({:b => 2})

すべての最後に、x の値は期待どおりに変更されましたが、@a_hash の値も変更されました。両方の値として {:a => 1, :b => 2} を取得しています。これはRubyの通常の動作ですか?

4

3 に答える 3

4

はい、インスタンス変数@a_hashとローカル変数は同じインスタンスへの参照xを格納します。このインスタンスを変更すると (オブジェクトを変更する mutator メソッドを使用して)、これらの変数は同じ値に評価されます。Hashmerge!

mergeオブジェクトのコピーを作成し、元のオブジェクトを変更しないメソッドを使用することができます。

@a_hash = {:a => 1}
x = @a_hash
y = x.merge({:b => 2})
# y => {:a => 1, :b => 2}
# x and @a_hash => {:a => 1}
于 2012-02-03T19:46:53.093 に答える
3

@a_hash は x へのリンクです。したがって、@a_hash を変更したくない場合は、次のようにする必要があります。

@a_hash = {:a => 1}
x = @a_hash.clone
x.merge!({:b => 2})
于 2012-02-03T19:48:39.267 に答える
1

はい、これは ruby​​ (および他のほとんどの言語) での通常の動作です。xとはどちらも@a_hash同じオブジェクトへの参照です。呼び出すmerge!ことで、そのオブジェクトを変更し、それを参照するすべての変数を通じてその変更を可視化できます。

その動作を望まない場合は、変更メソッドを使用しない (x = x.merge(...)代わりに使用する) か、変更する前にオブジェクトをコピーする (つまりx = @a_hash.dup) 必要があります。

于 2012-02-03T19:49:00.140 に答える