Ruby:对象深度复制

我正在研究一些在Ruby中深度复制对象的技术(MRI 1.9.3)。
我遇到了以下示例,但我不确定#dup方法的实现。 我测试了它并且它确实有效,但是我不理解该方法的逻辑步骤,因此我在自己的代码中使用它并不舒服。

语句@name = @name.dup是指副本中的iVar吗? 怎么样? 我看不到它。

请问有人解释一下吗?
还有,有更好的方法吗?

 class MyClass attr_accessor :name def initialize(arg_str) # called on MyClass.new("string") @name = arg_str # initialize an instance variable end def dup the_copy = super # shallow copy calling Object.dup @name = @name.dup # new copy of istance variable return the_copy # return the copied object end end 

这是一个非常薄的,非常具体的“深层复制”实现。 它的演示是在克隆中创建一个独立的@name实例变量,这样修改一个就地操作的名称就不会产生更改克隆的副作用。

通常,深度复制操作对于嵌套数组或散列之类的东西很重要,但它们也适用于具有引用该类事物的属性的任何对象。

在你的情况下,要使用更强大的dup方法创建一个对象,你应该对每个有问题的属性调用dup ,但我认为这个例子有点破碎。 它的作用是将原始文件中的@name替换为副本,这可能会破坏您拥有的任何引用。

更好的版本是:

 def dup copy = super copy.make_independent! copy end def make_independent! instance_variables.each do |var| value = instance_variable_get(var) if (value.respond_to?(:dup)) instance_variable_set(var, value.dup) end end end 

这应该具有复制支持dup方法的任何实例变量的效果。 这会跳过数字,布尔值和无法复制的内容。

当你执行super ,实例方法@name将在原始方法和副本之间共享。 通过执行@name = @name.dup ,原始@name = @name.dup获取字符串的新实例@name ,最终得到与复制实例具有的@name不同的@name