On Sun, 7 Dec 2003, A. Pagaltzis wrote:
> * Michel Rodriguez <[EMAIL PROTECTED]> [2003-12-06 18:41]:
> > I see 3 ways to do this:
>
> You forgot one:
>
> You say there are not typically hooks in the factory method to
> override what class gets instantiated. But there is! That hook is
> the constructor calls themselves. To override them, you need to
> replace the constructors. You do something like this:
>
> my $saved_constructor = \&Foo::Bar::Node::new;
> local *Foo::Bar::Node::new = sub {
> shift;
> local *Foo::Bar::Node::new = $saved_constructor;
> return Foo::SubclassBar::Node->new(@_);
> }
>
> If you call the factory method during the block this is in,
> it will create Foo::SubclassBar::Node objects instead of
> Foo::Bar::Node objects.
Indeed, internally that's more or less what the module does
> The inner local() is to make sure that in case the
> Foo::SubclassBar::Node constructor calls its superclass
> constructor, you don't go into endless recursion and it still
> works right.
>
> I don't see how you could reasonably make this snippet into an
> opaque module since the local() call has to be in your own
> function. At most, you might condense this to something like
Actually, by saving the original constructor in a separate package and by
inserting that package in the ISA of the sub class, I believe that the
ugliness is quite well hidden... until any of the constructors start
playing with @ISA. Have a look at the code of the module.
Thanks
--
Michel Rodriguez
Perl & XML
http://www.xmltwig.com