in reply to OO Perl: subclassing a class through an other one

I had to solve a similar problem recently and the approach I used was to define a method in the main class for creating the secondary class eg:

sub new_elt { my $self = shift; return XML::Twig::Elt->new(@_); }

Then if someone wants to subclass XML::Twig::Elt then they first need to override XML::Twig::new_elt() to return an object of the new class. eg:

sub XML::Twig::new_elt { my $self = shift; return my_elt_class->new(@_); }

Replies are listed 'Best First'.
Re^2: OO Perl: subclassing a class through an other one
by adrianh (Chancellor) on May 06, 2003 at 11:17 UTC

    Depending on the complexity of the other class it might be even simpler to encode the name of the other class as an overridable method. So in XML::Twig you have:

    sub elt_class { "XML::Twig::Elt" }; # in XML::Twig, every time it needs to create an element $self->elt_class->new;

    Then you just need to document elt_class and have your subclass override it as appropriate.

Re: Re: OO Perl: subclassing a class through an other one
by mirod (Canon) on May 06, 2003 at 11:21 UTC

    Interesting, thanks for the insight.

    I see 2 drawbacks to your method:

    • you have to subclass XML::Twig when what you want to subclass is really XML::Twig::Elt. This is probably better from a pure OO POV (is-it? Would any OO purist care to comment?), but a tad more verbose.
    • I would think it is a little slower too, as you add a layer of method calling instead of just a test on a field of the object. I would have to benchmark the 2 ways and compare them.

    So overall your way probably gets more OO-fu but mine wins for convenience and speed. I wonder if my way can break inheritance in some cases, I don't think so but I am no OO guru either.

      you have to subclass XML::Twig when what you want to subclass is really XML::Twig::Elt. This is probably better from a pure OO POV (is-it? Would any OO purist care to comment?), but a tad more verbose.

      I don't think either solution is more or less pure than the other. It depends on how you see people using the feature.

      My immediate feeling was that you would want to subclass XML::Twig since you would want to reuse the parser variant, rather than having to remember to pass the appropriate XML::Twig::Elt subclass in each time. Once And Only Once and all that.

      If you're going to be creating lots of one-off XML::Twig parsers passing the class as you originally proposed would probably be more sensible.

      I would think it is a little slower too, as you add a layer of method calling instead of just a test on a field of the object. I would have to benchmark the 2 ways and compare them.

      It would be trivial to cache the result of the method to reduce it to the hash-lookup case:

      # in XML::Twig::add_elt my $elt_class = $self->{elt_class} ||= $self->elt_class; my $e = $elt_class->new ;

      There is, of course, nothing stopping you having both mechanisms so you can subclass, or change it on an object-by-object basis. That way everybody's happy :-)