这种行为是否正确?我正在运行如下代码:
@a_hash = {:a => 1}
x = @a_hash
x.merge!({:b => 2})
最后,x的值已按预期更改,但@a_hash的值也是如此。我得到{:a => 1,:b => 2}作为两者的价值。这是Ruby中的正常行为吗?
答案 0 :(得分:4)
是的,实例变量@a_hash
和局部变量x
将引用存储到同一个Hash
实例,并且当您更改此实例时(使用mutator方法{ {1}}改变对象的位置),这些变量将被计算为相同的值。
您可能希望使用merge!
方法创建对象的副本,而不是更改原始对象:
merge
答案 1 :(得分:3)
@a_hash是指向x的链接。所以如果你想要@a_hash没有改变,你应该这样做:
@a_hash = {:a => 1}
x = @a_hash.clone
x.merge!({:b => 2})
答案 2 :(得分:1)
是的,这是ruby(以及大多数其他语言)中的正常行为。 x
和@a_hash
都是对同一对象的引用。通过调用merge!
,您可以通过引用它的所有变量更改该对象和可见变化。
如果您不想要这种行为,则不应使用变异方法(即改为使用x = x.merge(...)
)或在变异之前复制该对象(即x = @a_hash.dup
)。