This post originated from an RSS feed registered with Ruby Buzz
by Andrew Johnson.
Original Post: Deep Cloning
Feed Title: Simple things ...
Feed URL: http://www.siaris.net/index.cgi/index.rss
Feed Description: On programming, problem solving, and communication.
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).