1

我在编程方面是个外行,对 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 丢失了!如何确保在某个代码块中某个变量绝对不会更改?

提前感谢您的任何输入!!!

4

2 回答 2

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 提到的浅拷贝的效果。

于 2013-11-14T18:11:11.000 回答
0

Object#clone 保留了冻结属性和单例方法。如果您不需要这些,那么您的示例会发生什么, Object#dup 就足够了。

于 2013-11-14T19:40:32.593 回答