ruby非预期的变量赋值/更改

时间:2013-11-14 17:43:24

标签: ruby variables variable-assignment

我在编程方面非常熟练,而且对于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丢失了!如何确保在某个代码块中某个变量肯定没有改变?

提前感谢您的任何输入!

2 个答案:

答案 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足够了。