From: "Brian Schröder" Date: 2004-12-11T08:35:17+09:00 Subject: Re: How to make a deep copy of an object (Searching for Idiom) On Sat, 11 Dec 2004 08:27:25 +0900 Tim Hunter wrote: > Brian Schr�der wrote: > > > Hello Group, > > > > I sometimes which to make a deep copy of an object. I know I could use > > Marshal, but thats slow so I want to write a routine #deep_copy. (Or > > should I overwrite > > #dup ?) > > Brian, the classes in my new RVG library must have deep_copy methods. I > asked this question on c.l.r a few weeks ago but didn't get any > suggestions. I did some searching around and found some an old thread on > ruby_talk which helped, but with ruby-talk down I can't find it right now. > > The general form looks like this: > > def deep_copy > copy = self.class.new > ivs = instance_variables > ivs.each do |iv| > itv = instance_variable_get(iv) > otv = case > when itv.nil? > nil > when itv.respond_to?(:deep_copy) > itv.deep_copy > when itv.respond_to?(:dup) > itv.dup > else > itv > end > copy.instance_variable_set(iv, otv) > end > return copy > end > > The idea is that the instance variables can refer 1) to other objects that > have a deep_copy method, 2) to "normal" Ruby objects that can be duped, and > 3) to immediate objects like Fixnum which don't need to be duped, just > assigned. I also have a special case for nil since it responds to :dup but > can't actually be duped. > > If #initialize takes arguments, then you'll need a slightly different > version. > > For testing purposes I also implemented a deep_equal method with the same > general form. > > P.S. I'd appreciate any hearing any criticisms. > Interesting. But this won't work for instance variables that point to arrays of deep_copy-able objects. Right? Maybe this is connected to the "object-state" thread floating around somewehere else. Regards, Brian -- Brian Schr�der http://ruby.brian-schroeder.de/