Suppose I have an class that needs to implement its own dup/clone
methods.  What is the correct way to write these methods?

One way is to create protected accessors:

  class Foo
    def initialize(foo, bar)
      @foo = foo
      @bar = bar
    end

    def dup
      copy = super
      copy.foo = @foo.dup
      copy.bar = @bar.dup
    end

    protected
    attr_accessor :foo
    attr_accessor :bar
  end

Another way is to use instance_eval:

  class Foo
    def dup
      copy = super
      foo = @foo.dup
      bar = @bar.dup
      copy.instance_eval do
        @foo = foo
        @bar = bar
      end
    end
  end

Questions:

1. How else might dup/clone be implemented?  (the deep-copy trick using
   marshaling is one way, but the goal here is to write a one-level-deep
   dup/clone).

2. What is the right way to set the new instance variables in the copy?

3. Should dup be implemented in terms of clone or should clone be
   implented in terms of dup (or should they both be implemented
   independently or in terms of another function)?

4. When making the copy, is super the right way to make the copy, or
   should allocate be used? (allocate doesn't work on 1.6.x, which I
   still use heavily, though if it's the right solution, then it's the
   right solution).

5. Certain types cannot be dup'd (e.g. NilClass in all versions of Ruby
   or Fixnum in 1.8 and later), so the above code will break if I write:

     Foo.new(10, 42).dup

   Is it possible (or is it even wise) to write a dup or clone function
   that works with both value types and container types?

Paul