我在编程方面非常熟练,而且对于ruby来说是一个菜鸟但是我觉得它对我的工作很有用。我很好地研究了一个相当大的脚本,它带来了以下意想不到的效果:
def my_reduce_method(value_hash,some_keys)
value_hash.delete(some_keys)
end
puts all_values
=> all_values
some_values = all_values # start my block with all values (class: hash)
some_values = my_reduce_method(some_values,keys_to_reduce)
# here only some_values should be effected!
puts all_values
=> some_values
在街区中没有任何损坏,但原来的all_values丢失了!如何确保在某个代码块中某个变量肯定没有改变?
提前感谢您的任何输入!
答案 0 :(得分:1)
Ruby中的所有对象分配都是参考分配。
这意味着,当你这样做时:
some_values = all_values
您正在复制all_values
引用(或指向)的对象的引用(或地址)。
您案例的解决方案很简单:
some_values = all_values.clone
.dup
通常也有效(根据对象的不同而不同)。
另外需要注意的是,当all_values[:x]
有一个字符串时你会这样做:
some_values = all_values.clone
some_values[:x] += 'abc'
这不会更改all_values[:x]
,因为some_values[:x]
获取(已分配)新的字符串对象。
但如果你这样做:
some_values = all_values.clone
some_values[:x] << 'abc'
all_values[:x]
和some_values[:x]
都会更改,因为它们都引用相同的字符串对象。
这是浅拷贝 @Plasmarob提到的效果。
答案 1 :(得分:0)
Object#clone保留冻结属性和单例方法。如果你 不需要那些,你的例子会发生什么,Object#dup足够了。