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
?
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With