Module: Configatron::DeepClone
- Defined in:
- lib/configatron/deep_clone.rb
Class Method Summary collapse
Class Method Details
.deep_clone(obj = self, cloned = {}) ⇒ Object
DeepClone
Version
1.2006.05.23.configatron.1 (change of the first number means Big Change)
Description
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.
Usage
(see examples directory under the ruby gems root directory)
require 'rubygems'
require 'deep_clone'
include DeepClone
obj = []
a = [ true, false, obj ]
b = a.deep_clone
obj.push( 'foo' )
p obj # >> [ 'foo' ]
p b[2] # >> []
Source
simplypowerful.1984.cz/goodlibs/1.2006.05.23
Author
jan molic (/mig/at_sign/1984/dot/cz/)
Licence
You can redistribute it and/or modify it under the same terms of Ruby's license;
either the dual license version in 2003, or any later version.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/configatron/deep_clone.rb', line 37 def self.deep_clone( obj=self, cloned={} ) if Configatron::RootStore === obj # We never actually want to have multiple copies of our # Configatron::RootStore -- when making a temp, we just stick # the state-to-revert-to into an ivar. return obj elsif Configatron::Store === obj # Need to special-case this since it's a BasicObject, meaning it # doesn't respond to all the usual ivar magic methods cl = obj.clone(cloned) cloned[obj.__id__] = cl cloned[cl.__id__] = cl return cl elsif cloned.key?( obj.__id__ ) return cloned[obj.__id__] else begin cl = obj.clone rescue Exception # unclonnable (TrueClass, Fixnum, ...) cloned[obj.__id__] = obj return obj else cloned[obj.__id__] = cl cloned[cl.__id__] = cl case when Hash === cl cl.clone.each do |k,v| cl[k] = deep_clone( v, cloned ) end when Array === cl cl.collect! do |v| deep_clone( v, cloned ) end end cl.instance_variables.each do |var| v = cl.instance_eval( var.to_s ) v_cl = deep_clone( v, cloned ) cl.instance_eval( "#{var} = v_cl" ) end return cl end end end |