この動作は正しいですか?私は、次のようないくつかのコードを実行している:ハッシュマージの動作
@a_hash = {:a => 1}
x = @a_hash
x.merge!({:b => 2})
をすべてのことの終わりには、Xの値が予想されるように変更したがそう@a_hashの値を持ってきました。私は両方の値として{:a => 1、:b => 2}を得ています。 Rubyではこれが正常な動作ですか?
この動作は正しいですか?私は、次のようないくつかのコードを実行している:ハッシュマージの動作
@a_hash = {:a => 1}
x = @a_hash
x.merge!({:b => 2})
をすべてのことの終わりには、Xの値が予想されるように変更したがそう@a_hashの値を持ってきました。私は両方の値として{:a => 1、:b => 2}を得ています。 Rubyではこれが正常な動作ですか?
はい、インスタンス変数同じHash
インスタンスへの参照、あなたは、このインスタンスを変更する場合(所定の位置にオブジェクトを変更するミューテータメソッドmerge!
を使用して)は、これらの変数が同じ値に評価されます@a_hash
とローカル変数x
店。
@a_hash = {:a => 1}
x = @a_hash
y = x.merge({:b => 2})
# y => {:a => 1, :b => 2}
# x and @a_hash => {:a => 1}
@a_hashは、Xへのリンクです:
あなたは、オブジェクトのコピーを作成し、オリジナルのものを変更しないmerge
方法を使用することをお勧めします。あなたが変更されていない@a_hashたいのであれば、あなたは次のように実行する必要があります。
@a_hash = {:a => 1}
x = @a_hash.clone
x.merge!({:b => 2})
'x = @ a_hash.merge(:b => 2)'と完全に同等である場合はクローン化することをお勧めしません。 – tokland
はい、それはルビー(および他のほとんどの言語)での正常な動作です。 x
と@a_hash
は同じオブジェクトへの参照です。 merge!
を呼び出すと、そのオブジェクトが変更され、そのオブジェクトを参照するすべての変数を通じてその変更が表示されます。
このような動作をしたくない場合は、突然変異するメソッド(代わりにx = x.merge(...)
を使用)を使用するか、オブジェクトを変更する前にコピーしてください(例:x = @a_hash.dup
)。
ああ、大丈夫です。私はそれが起こっていると思った。ありがとう。 – blim8183