Ruby: (Deep) Copy Object
I wanted to make an object. Then copy it. Then change that copy and leave original object intact. But I did not know how to do it. When I do not know how to do something, I always ask wtr-general mailing list. I posted my question. Then I though it would be nice if I explained why I want to copy an object. But it got pretty long, so I put it at my blog.
I got a reply. “Try Object#clone”. Could it be that easy?! It could be. After all, this is Ruby. But no, it is not that easy. It did not work. Original object was changing with it’s duplicate.
class Page
attr_accessor :texts
def initialize(url, texts)
@url, @texts = url, texts
end
end
page_view = Page.new(“app.com/view.aspx”, ["File > View"])
page_view_after_add = page_view.clone
page_view_after_add.texts << “File added.”
puts page_view.inspect
puts page_view_after_add.inspect
Output:
#<Page:0x2820ae0 @url="app.com/view.aspx", @texts=["File > View", "File added."]>
#<Page:0x2820a98 @url="app.com/view.aspx", @texts=["File > View", "File added."]>
But now I new where to look. So I typed "ri Object#clone" and "ri Object#dup" at Command Prompt (and even looked at http://www.ruby-doc.org/core/). It said (at both places, for both Object#clone and Object#dup):
"Produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference."
So, it creates a "shallow" copy. I do not need this. I need a "real" copy.
Google helped me. I searched for "ruby copy object" and found http://www.rubygarden.org/ruby?Make_A_Deep_Copy_Of_An_Object. Secret word is "deep" copy.
I added this to class Page (and replaced page_view.clone with page_view.deep_clone) and got what I needed!
def deep_clone
Marshal::load(Marshal.dump(self))
end
Output:
#<Page:0x4c1dd10 @url="app.com/view.aspx", @texts=["File > View"]>
#<Page:0x4c1dc50 @url="app.com/view.aspx", @texts=["File > View", "File added."]>
I do not understand how it works, and I do not care, as long as it works.

The way your solution works is pretty easy. It serializes the data out to text and then loads it up into a new set of objects. That may cause some overhead though. The only other way to do a deep copy is to recursively clone/dup each instance variable.
Nolan Eakins
21 Mar 07 at 9:27 pm
Thanks a lot about this useful tip. I am working on the Ruby programming assignment in the Programming Language class and the prof want us to code a deep dup method for a class. It seems I find a solution from you. Thank you.
aoaoniu1985
2 Mar 08 at 8:21 am
[...] You are probably from US, Croatia, India, or UK. Top 5 content is front page, Watir category, Ruby: (Deep) Copy Object post (a surprise for me), e-mail category and about me [...]
Željko Filipin’s Blog on Software Testing » Who are you?
19 Mar 08 at 10:12 pm
Wow! This is just what I was looking for and it made my fix very easy. I had a case where it seemed more natural to pass an entire object to a method but it necessarily needed to do some destructive changes to it while doing its thing.
I suppose if I had realized earlier that Ruby passes everything by reference and that if I passed an object to a method, then even though the local identifier to it is a copy, the thing it points to is still the same object then I might have designed it differently.
Unless I have a completely wrong paradigm, I would think making copies of objects is a rather common thing to want to do, I’m glad you found a nice easy way to do it. I would have thought that wth Ruby, every class would automatically have some kind of “deep_clone” method builtin.
Perhaps the popularity of this page is an indication that this is big missing?
daltxguy
20 May 08 at 1:13 pm
As far as I remember, deep copy is intentionally not implemented because it’s use is discouraged.
Željko Filipin
20 May 08 at 1:55 pm
agreed. it’s one of the do-what-you-mean things … if you need deep copying, it’s probably something you really need to implement by hand …
which i sorta am having to do now. my structure has Procs which can’t be serialized … perhaps you could extend the code found here:
http://www.artima.com/forums/flat.jsp?forum=123&thread=40913
but the list of ‘klone = self’ exception cases is sort of a hack. still, like you said @zeijko, as long as it works!
Dan Foley
14 Feb 09 at 8:49 am