Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

clone

ruby

dup

I have a Pointer class with a single attribute :contents, that points to an object of class 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. I know that #dup method is defined by default, while #clone method is expected to be overriden to be able to make deep copies. 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? Or should I refrain from overridine #dup, because I am not "supposed to" and override #clone with a method making shallow copies?

I would welcome comments on the above, but let's say that I will choose to override #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". Also, this guy writes about #initialize_clone, #initialize_dup and #initialize_copy in Ruby. 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?

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?

Also, the same question apply to #clone - should I try to define #initialize_clone or just #clone?

like image 816
Boris Stitnicky Avatar asked Aug 14 '12 02:08

Boris Stitnicky


People also ask

What is DUP method in Ruby?

Ruby | Numeric dup() function The dup() is an inbuilt method in Ruby returns the number itself. Syntax: num1.dup() Parameters: The function needs a number. Return Value: It returns itself only.

What is Deep_dup?

The #deep_dup method in Rails method returns true . This means that an instance that contains the Object class in its ancestor chain is eligible to deep copy.

How do you copy an object in Ruby?

Ruby does provide two methods for making copies of objects, including one that can be made to do deep copies. The Object#dup method will make a shallow copy of an object. To achieve this, the dup method will call the initialize_copy method of that class. What this does exactly is dependent on the class.


1 Answers

From my experience, overloading #initialize_copy works just fine (never heard about initialize_dup and 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:

class MyClass
  def initialize_copy(orig)
    super
    # Do custom initialization for self
  end
end
like image 86
sylvain.joyeux Avatar answered Sep 19 '22 15:09

sylvain.joyeux