Siaris

Deep Cloning
03 Feb 04 - http://www.siaris.net/index.cgi/Programming/LanguageBits/Ruby/DeepClone.rdoc

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).