在Ruby类上定义哪种方法为其实例提供dup / clone?

时间:2012-08-14 02:55:40

标签: ruby clone dup

我有一个Pointer类,其中包含一个属性:contents,它指向类MyObject的对象。

class MyObject
  def hello; "hello" end
end

class Pointer
  attr_reader :contents
  def initialize( cont ); @contents = cont end
  # perhaps define some more state
end

我希望我的Pointer能够复制自己。我知道#dup方法是默认定义的,而#clone方法应该被覆盖以便能够进行深层复制。但在这里,副本不必太深。所以,我遇到的第一个困境是,我应该覆盖#dup方法,因为我真的不想复制Pointer的其他状态,只需创建一个指向同一个MyObject的新状态。 {1}}实例?或者我应该避免覆盖#dup,因为我不是“应该”并用一个制作浅拷贝的方法覆盖#clone

我欢迎对上述内容发表评论,但我们会说我会选择覆盖#dup。我可以做到这一点:

class Pointer
  def dup; self.class.new( contents ) end
end

但在线,我读过“ dup 方法会调用初始化副本方法”。此外,this guy在Ruby中撰写了关于#initialize_clone#initialize_dup#initialize_copy的内容。这让我感到疑惑,是最好的做法也许就是这样吗?

class Pointer
  def initialize_copy
    # do I don't know what
  end
end

或者喜欢这个?

class Pointer
  def initialize_dup
    # do I don't know what
  end
end

或者,我是否应该忘记为了让初学者感到困惑而写的网上咆哮,并且不顾一切地覆盖#dup

此外,我确实理解我可以在不定义任何自定义#dup的情况下致电#dup,但 if 我想用不同的行为定义#dup

此外,同样的问题适用于#clone - 我应该尝试定义#initialize_clone还是#clone

1 个答案:

答案 0 :(得分:17)

根据我的经验,重载#initialize_copy工作正常(从未听说过initialize_dup和initialize_clone)。

原始的initialize_copy(使用原始对象的值初始化每个实例变量)可以通过super获得,所以我通常会这样做:

class MyClass
  def initialize_copy(orig)
    super
    # Do custom initialization for self
  end
end