Siaris
Simple Things
Syndicate: full/short
Siaris
Categories
General0
News2
Programming2
LanguageBits0
Perl50
Ruby10
VersionControl1
Misc1
Article Calendar
<= May, 2008
S M T W T F S
123
45678910
11121314151617
18192021222324
25262728293031
Search this blog

Key links
External Blogs
Brought to you by ...
Ruby
1and1.com

Deep Cloning

Andrew L. Johnson

One problem with both Ruby’s #dup and #clone methods is that they only provide shallow copying. That suffices for many purposes, but sometimes you want deeper copying. A pretty standard method for deep copying Ruby objects is to use the Marshal module’s #load and #dump methods:

    class Object
      def deep_clone
        Marshal::load(Marshal.dump(self))
      end
    end

As long the object in question is serializable and doesn’t have singleton methods installed, that works. The following is a very bare-bones first cut at another deep clone method:

    class Object
      def dclone
        case self
          when Fixnum,Bignum,Float,NilClass,FalseClass,
               TrueClass,Continuation
            klone = self
          when Hash
            klone = self.clone
            self.each{|k,v| klone[k] = v.dclone}
          when Array
            klone = self.clone
            klone.clear
            self.each{|v| klone << v.dclone}
          else
            klone = self.clone
        end
        klone.instance_variables.each {|v|
          klone.instance_variable_set(v,
            klone.instance_variable_get(v).dclone)
        }
        klone
      end
    end

Singleton methods are handled by #clone, and attributes are recursively #dclone‘d (as are elements of Arrays and Hashes).