Ruby:对象深度复制 [英] Ruby: object deep copying
问题描述
我正在研究在Ruby中深度复制对象的一些技术(MRI 1.9.3)。
我遇到了以下示例,但是我不确定 #dup
方法实现。
我测试了它,它确实起作用了,但是我不了解该方法的逻辑步骤,因此,在自己的代码中使用它并不感到舒适。
I'm looking at some techniques to deep-copy objects in Ruby (MRI 1.9.3).
I came across the following example, but I'm not sure about the #dup
method implementation.
I tested it and it does work, but I don't understand the logical steps of the method, thus I'm not confortable using it in my own code.
语句 @name = @ name.dup
是指iVar 内部副本?怎么样?我看不到。
Is the statement @name = @name.dup
referring to the iVar inside the copy? How? I can't see it.
有人可以解释吗?
另外,还有更好的方法吗?
Could anyone explain it, please?
Also, are there better ways?
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
实例变量,以便使用就地操作修改一个实例的名称不会产生更改的副作用
This is a really thin, very specific implementation of a "deep copy". What it's demonstrating is creating an independent @name
instance variable in the clone so that modifying the name of one with an in-place operation won't have the side-effect of changing the clone.
通常,深层复制操作对于诸如嵌套数组或散列之类的事情很重要,但它们也适用于具有引用该事物的属性的任何对象
Normally deep-copy operations are important for things like nested arrays or hashes, but they're also applicable to any object with attributes that refer to things of that sort.
在您的情况下,要使对象具有更强大的 dup
方法,应调用 dup
放在每个有问题的属性上,但是我认为这个示例有点破损。它的作用是将原件中的 @name
替换为副本,这可能会破坏您的引用。
In your case, to make an object with a more robust dup
method, you should call dup
on each of the attributes in question, but I think this example is a bit broken. What it does is replace the @name
in the original with a copy, which may break any references you have.
更好的版本是:
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
这应该具有复制任何支持<$的实例变量的作用。 c $ c> dup 方法。这样会跳过数字,布尔值和 nil
等不能重复的内容。
This should have the effect of duplicating any instance variables which support the dup
method. This skips things like numbers, booleans, and nil
which can't be duplicated.
这篇关于Ruby:对象深度复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!