On Jan 22, 7:39 pm, Ken Bloom <kbl... / gmail.com> wrote:

> Basically, I think it should be possible for an object to encapsulate
> (and hide) member variables that should be copied (not shared) when the
> enclosing object is copied. Thus, a semi-deep copying version of #clone
> and #dup are in order. That seems to be what Cloneable is about.
>
> Thanks for pointing out #initialize_copy. I didn't know it existed. Now I
> see it in PickAxe, but I think it's role has been greatly trivialized.
> Pickaxe only mentions it with regard to C extensions, empathetically says
> that it's only for C extensions, and completely overlooks the idea that
> an object might be hiding other kinds of information that should be
> copied, not shared between duplicates.
>
> Might I suggest that instead of overriding #dup and #clone at all,
> Cloneable should just provide the following implementation for
> #initialize_copy, then we can make #dup and #clone will both behave
> properly by virtue of the fact that they descend from Object#dup and
> Object#clone:
>
> module Cloneable
>   def initialize_copy sibling
>     #first duplicate my superclass' state. Note that if it's duplicating
>     #instance variables, this will be overwritten, but this is important
>     #because we could be dealing with a C extension with state hidden from
>     #the Ruby interpreter
>     super
>
>     #we want to know if we're being dup'ed or clone'd, because we want to
>     #preserve the state of our internals the same way our state is being
>     #preserved.
>     #(If we can't figure it out, we'll just use #dup)
>     operation=caller.find{|x| x !~ /`initialize_copy'/}.
>       match(/`(dup|clone)'/)[1] or :dup
>
>     sibling.instance_variables.each do |ivar|
>       value = sibling.instance_variable_get(ivar)
>
>       #set my instance variable to be a #dup or #clone
>       #or my sibling, depending on what's happening to me right now
>       instance_variable_set(ivar, value.send(operation))
>     end
>   end
> end

Thanks for this Ken. I've adopted this code as given --I could not
think of better way to determine if dup or clone was being used. If
anyone knows of a more robust way to determine dup vs. clone please
let me know.

Thanks,
T.