Brian Schröäer 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.