I’m needing to implement a deep copy operation on a couple of objects,
and was wondering if there was a “best practices” for this sort of
thing. I’ve seen the Marshal.load(Marshal.dump()) idiom, but I’m using
singleton classes which can’t be dumped. So I’m implementing my deep
copy similar to:
def deep_copy
other = self.clone
other.instance_var_1 = self.instance_var_1.clone
other.instance_var_2 = self.instance_var_2.deep_copy
other
end
where some of the instance variables are objects for which I’ve written
a deep_copy method.
The biggest problem with this method (that I can see), is that all of
the attributes of the object need to be publically writable, which is
undesirable. Is there a better way to do this sort of thing?
I’m needing to implement a deep copy operation on a couple of objects,
and was wondering if there was a “best practices” for this sort of
thing. I’ve seen the Marshal.load(Marshal.dump()) idiom, but I’m using
singleton classes which can’t be dumped.
It seems they can be dumped - but you get another instance:
where some of the instance variables are objects for which I’ve written
a deep_copy method.
The biggest problem with this method (that I can see), is that all of
the attributes of the object need to be publically writable, which is
undesirable. Is there a better way to do this sort of thing?
You can use #instance_variable_get and #instance_variable_set to access
them.
Did you consider overriding #dup and / or #clone for this? Typically
you would not want a cloned / duped instance to refer to the original
instance’s instance variables (at least if they are mutable like
collections, strings and other objects).
I’m needing to implement a deep copy operation on a couple of objects,
and was wondering if there was a “best practices” for this sort of
thing. I’ve seen the Marshal.load(Marshal.dump()) idiom, but I’m using
singleton classes which can’t be dumped.
It seems they can be dumped - but you get another instance:
… seems to work just fine, so I’m not quite sure what is going on with
my code, as I still get a “TypeError: singleton can’t be dumped” from
Marshal.dump. I’ll have to play around with it a bit more.
You can use #instance_variable_get and #instance_variable_set to access
them.
Sweet, thanks!
Did you consider overriding #dup and / or #clone for this? Typically
you would not want a cloned / duped instance to refer to the original
instance’s instance variables (at least if they are mutable like
collections, strings and other objects).
Yeah, but I can’t seem to wrap my head around the recursive cloning.
For example, in the above scenarion (A::C), how do I allocate space
for the new object without calling clone/dup? I.e, I’m sure that you
realize the problem with the following:
class A
class B
class C
def clone
other = self.clone
end
end
end
end
So how do I get the “other” object within the clone method? Do I need
to allow my initialize method to take in an object of the same type and
perform all the work of the clone method, or is there a better way?
To clone an object, you should define the #initialize_copy method in
your class. This method takes the object to copy from, in argument. It
is used by #clone and #dup to perform the initialization of the cloned
object.