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 &amp; XML
http://www.xmltwig.com

Reply via email to