Re: Duplication from a Subclass, Object#become

From: ts [mailto:[email protected]]

G> class Foo
G> def dup
G> # strange, magical, important things happen here
G> # which know about all of Foo’s instance variables

You can’t use #initialize_copy ?

No. In this case, “Foo” is actually REXML::Element. Because these
objects store all their attributes in an Attributes instance, a standard
(shallow) dup leaves them referencing the same attribute set:

irb(main):001:0> require ‘rexml/document’
=> true
irb(main):002:0> e1 = REXML::Element.new( ‘foo’ )
=>
irb(main):003:0> e1.attributes[ ‘bar’ ] = ‘whee’
=> “whee”
irb(main):004:0> e2 = e1.dup
=>
irb(main):005:0> e2.attributes[ ‘la’ ] = ‘dee da’
=> “dee da”
irb(main):006:0> e1
=>

So, I really want to use Element#clone, but it returns an REXML::Element
instance when called from my subclass, and I have no control over its
source code.

Gavin K. wrote:

So, I really want to use Element#clone, but it returns an REXML::Element
instance when called from my subclass, and I have no control over its
source code.

FWIW, I found that I was able to do (typing from memory):

class Foo < REXML::Element
def clone
klone = self.class.superclass.method( :new ).unbind.bind(
self.class ).call( self )
# my stuff here
klone
end
end

…but I think I’ll probably end up re-writing my class to
wrap/delegate to Element, instead of directly inheriting from it. Pity,
from an rdoc standpoint.

Phrogz wrote:

self.class ).call( self )
# my stuff here
klone
end
end

…but I think I’ll probably end up re-writing my class to
wrap/delegate to Element, instead of directly inheriting from it. Pity,
from an rdoc standpoint.

I have to agree with you. Again and again I use subclassing and it
turns out to be more trouble than it’s worth. Delegating always seems
to be a better course. It seems to me it’s sort of like duck typing.
Unfortuately delegating means not being able to easily get under the
hood of the “super class”, e.g. super and instance variables. I wonder
it some utility methods could help ease that.

T.