From: Robert Klemme Date: 2009-10-16T20:25:44+09:00 Subject: Re: deep cloning, how? 2009/10/16 lith : >> But I think the spirit of dup >> described above is that dup defined in a subclass should initialize it >> using its constructor. Brian, I disagree. The proper way is to implement #initialize_copy. That way you can make sure you do not get aliasing effects even if source and copy are frozen because in #initialize_copy frozen state is not applied. > I'd understand the description in such a way that user should > override > neither #dup not #clone but instead create a #initialize_copy method > to > implement anything class-specific (including a non-shallow copy). Also for shallow copy in order to avoid aliasing! IMHO a proper setup looks like this: class A attr_reader :x attr_accessor :y def initialize @x = [] @y = 10 end def initialize_copy(source) super # p self @x = source.x.dup end end class B < A attr_accessor :z def initialize super() @z = {} end def initialize_copy(source) super @z = source.z.dup end end Note that the copy is initialized with the same set of references when entering #initialize_copy so you need only deal with members that could cause aliasing issues (unfrozen strings and collections for example). > Since > that method is called by #clone and #dup and the frozen/tainted state > could be easily reset, I personally still don't quite understand why > there are two methods. You cannot reset frozen state - for good reasons. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/