From: Robert Klemme Date: 2004-12-11T19:42:23+09:00 Subject: Re: How to make a deep copy of an object (Searching for Idiom) [Object State] "Brian Schr�der" schrieb im Newsbeitrag news:20041211105957.76dae75d@black.wg... > On Sat, 11 Dec 2004 09:22:24 +0900 > Tim Hunter wrote: > >> Brian Schr�der wrote: >> >> > Interesting. But this won't work for instance variables that point to >> > arrays of deep_copy-able objects. Right? >> >> I knew you'd spot that :-) In a couple of cases I had to replace Arrays >> with >> something like this: >> >> class Content < Array >> def deep_copy >> copy = self.class.new >> each do |c| >> copy << case >> when c.nil? >> nil >> when c.respond_to?(:deep_copy) >> c.deep_copy >> when c.respond_to?(:dup) >> c.dup >> else >> c >> end >> end >> return copy >> end >> end >> >> And, yes, I have to be careful not to use methods that return Array >> objects. >> > > Maybe it would make sense to extend the base classes Object, Array, Hash > with a > deep-copy functionality. That would be something for the extensions > project. IMHO not. Reason beeing that the semantics of deep copy are class dependend. You might not want to copy all instances in an object graph for deep copy and that might totally depend on the class at hand and / or (even worse) application. IMHO there is no real general solution to thid. Of course you could define a method in Object like def deep_copy Marshal.load( Marshal.dump( self ) ) end but you don't gain much that way. And it won't even work in the general case (consider Singletons etc.). > The problem here is, that we have object state that is not contained in > "visible slots" i.e. instance variables. So this would be one case, where > the > proposal for a There's a much more serious problem with the proposed implementation: it does not cope with graphs of objects that contain cycles. Do do that you need to keep track of objects copied already. Marshal does this - and it's efficient. If you want to do that yourself, you'll likely need a hash[old oid -> copy] to manage this. I doubt though that it's more efficient than Marshal. I had to discover that there's more to deep copying than just traversing the object graph and copying each instance in turn a while ago myself. I help you can benefit from my earlier errors... :-) Kind regards robert