哈希合并行为
问题描述:
此行为是否正确?我跑了一些类似于下面的代码:哈希合并行为
@a_hash = {:a => 1}
x = @a_hash
x.merge!({:b => 2})
在所有的结束,X的值已经改变预期,但如此有@a_hash值。我将{:a => 1,:b => 2}作为它们的值。这是Ruby中的正常行为吗?
答
是,实例变量@a_hash
和局部变量x
商店参考到相同Hash
实例,并当改变此实例(使用增变方法merge!
到位改变对象),这些变量将被评估为相同的值。
您可能需要使用merge
方法创建对象的副本,不改变原来的一个:
@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。所以,如果你想@a_hash没有改变,你应该这样做:
@a_hash = {:a => 1}
x = @a_hash.clone
x.merge!({:b => 2})
+2
当我完全等价于'x = @ a_hash.merge(:b => 2)时,我不推荐克隆' – tokland 2012-02-03 20:22:25
答
是的,这是红宝石(和大多数其他语言)的正常行为。 x
和@a_hash
都是对同一个对象的引用。通过调用merge!
您更改该对象,并通过引用它的所有变量更改可见。
如果您不想要这种行为,您应该不使用变异方法(即使用x = x.merge(...)
)或在变异之前复制对象(即x = @a_hash.dup
)。
啊,好的。我怀疑那是发生了什么事。谢谢。 – blim8183 2012-02-03 19:49:45