Sha256: 11f0ce1434d2b59d22bd87388f756562723f4643f74942a90a3ecb4ca6c7fbd0

Contents?: true

Size: 1.26 KB

Versions: 10

Compression:

Stored size: 1.26 KB

Contents

#--
# Credit goes to Jan Molic.
#++

module Kernel

  # Adds deep_clone method to an object which produces deep copy of it. It means
  # if you clone a Hash, every nested items and their nested items will be cloned.
  # Moreover deep_clone checks if the object is already cloned to prevent endless recursion.
  #
  #   obj = []
  #   a = [ true, false, obj ]
  #   b = a.deep_clone
  #   obj.push( 'foo' )
  #   p obj   # >> [ 'foo' ]
  #   p b[2]  # >> []

  def deep_clone( obj=self, cloned={} )
    if cloned.has_key?( obj.object_id )
      return cloned[obj.object_id]
    else
      begin
        cl = obj.clone
      rescue Exception
        # unclonnable (TrueClass, Fixnum, ...)
        cloned[obj.object_id] = obj
        return obj
      else
        cloned[obj.object_id] = cl
        cloned[cl.object_id] = cl
        if cl.is_a?( Hash )
          cl.clone.each { |k,v|
            cl[k] = deep_clone( v, cloned )
          }
        elsif cl.is_a?( Array )
          cl.collect! { |v|
                  deep_clone( v, cloned )
          }
        end
        cl.instance_variables.each do |var|
          v = cl.instance_eval( var )
          v_cl = deep_clone( v, cloned )
          cl.instance_eval( "#{var} = v_cl" )
        end
        return cl
      end
    end
  end

end

Version data entries

10 entries across 10 versions & 1 rubygems

Version Path
facets-1.7.0 lib/facets/core/kernel/deep_clone.rb
facets-1.7.30 lib/facets/core/kernel/deep_clone.rb
facets-1.7.38 lib/facets/core/kernel/deep_clone.rb
facets-1.7.46 lib/facets/core/kernel/deep_clone.rb
facets-1.8.49 lib/facets/core/kernel/deep_clone.rb
facets-1.8.0 lib/facets/core/kernel/deep_clone.rb
facets-1.8.20 lib/facets/core/kernel/deep_clone.rb
facets-1.8.51 lib/facets/core/kernel/deep_clone.rb
facets-1.8.54 lib/facets/core/kernel/deep_clone.rb
facets-1.8.8 lib/facets/core/kernel/deep_clone.rb