"Brian Schr?der" <ruby / brian-schroeder.de> schrieb im Newsbeitrag 
news:20041211105957.76dae75d / black.wg...
> On Sat, 11 Dec 2004 09:22:24 +0900
> Tim Hunter <cyclists / nc.rr.com> 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