简体   繁体   English

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

[英]Which method to define on a Ruby class to provide dup / clone for its instances?

I have a Pointer class with a single attribute :contents , that points to an object of class MyObject . 我有一个带有单个属性的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

I want my Pointer to be able to make copies of itself. 我希望我的Pointer能够复制自己。 I know that #dup method is defined by default, while #clone method is expected to be overriden to be able to make deep copies. 我知道#dup方法是默认定义的,而#clone方法应该被覆盖以便能够进行深层复制。 But here, the copies don't have to be too deep. 但在这里,副本不必太深。 So, the first dilemma that I have is, should I override #dup method, because I don't really want to copy the additional state of my Pointer , just make a new one pointing to the same MyObject instance? 所以,我#dup的第一个困境是,我应该覆盖#dup方法,因为我真的不想复制Pointer的附加状态,只需创建一个指向同一个MyObject实例的新状态? Or should I refrain from overridine #dup , because I am not "supposed to" and override #clone with a method making shallow copies? 或者我应该避免覆盖#dup ,因为我不是“应该”并用一个制作浅拷贝的方法覆盖#clone

I would welcome comments on the above, but let's say that I will choose to override #dup . 我欢迎对上述内容进行评论,但是我要说我会选择覆盖#dup I could do just this: 我能做到这一点:

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

But online, I read something like "the dup method will call the initialize copy method". 但是在网上,我读过类似“ dup方法将调用初始化复制方法”的内容。 Also, this guy writes about #initialize_clone , #initialize_dup and #initialize_copy in Ruby. 此外, 这个人在Ruby中写了#initialize_clone#initialize_dup#initialize_copy That leaves me wondering, is the best practice perhaps like this? 这让我感到疑惑,是最好的做法也许是这样的?

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

Or like this? 或者像这样?

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

Or should I just forget about online rants written to confuse beginners and go for overriding #dup without concerns? 或者,我是否应该忘记编写的混淆初学者的在线咆哮,并且#dup重写#dup

Also, I do understand that I can just call #dup without defining any custom #dup , but what if I want to define #dup with different behavior? 另外,我也明白,我可以叫#dup没有定义任何自定义#dup ,但如果我要定义什么#dup具有不同的行为?

Also, the same question apply to #clone - should I try to define #initialize_clone or just #clone ? 此外,同样的问题适用于#clone - 我应该尝试定义#initialize_clone还是#clone

From my experience, overloading #initialize_copy works just fine (never heard about initialize_dup and initialize_clone). 根据我的经验,重载#initialize_copy工作正常(从未听说过initialize_dup和initialize_clone)。

The original initialize_copy (which initializes every instance variable with the values from the original object) is available through super, so I usually do: 原始的initialize_copy(使用原始对象的值初始化每个实例变量)可以通过super获得,所以我通常会这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM