in reply to Real live usage of inheritance?

Take a look at HTML::TokeParser::Simple. That module inherits from HTML::TokeParser. It obeys the Liskov Substitution Principle, it truly extends the functionality and, I think, is a decent example of what inheritance can do (though it would be better if blessing the tokens had been pushed down to the parent classes).

One problem with inheritence is determining what should really be inherited. For example, I see a lot of inheritence with no purpose other than to alter the object's data (that should probably be an instance) rather than altering (or extending) the object's behavior.

Also, just because you can inherit from something doesn't mean you should. For example. one time I was creating a set of Web tests and inherited from WWW::Mechanize. Instead of an is-a relationship, I actually had a has-a relationship and I needed to rewrite my code to delegate method calls to a Mechanize object. While this was a good thing to do from a design standpoint, it was doubly important in Perl as it's so easy to accidentally step on the "private" methods of a class:

package Foo; sub new { my $self = bless {}, shift; $self->_init } sub _init { 'initialize data here' } package Bar; use base 'Foo'; sub _init { warn "We didn't initialize our data :(\n" } package main; my $thing = Bar->new;

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re: Re: Real live usage of inheritance?
by hardburn (Abbot) on Nov 05, 2003 at 19:03 UTC

    it was doubly important in Perl as it's so easy to accidentally step on the "private" methods of a class:

    In the case you present, I would argue that if the base methods are truly private, they should have been implemented as lexically scoped closures (declare my $init = sub { }; at the top of the package), not as a regular subroutine.

    It'd be nice if we could do away with the _subroutine_name idiom all together, but Perl doesn't currently provide a way to do protected methods (except by doing some fooling around with caller and isa, and even then it's only a runtime error), so the leading-underscore trick is the next best option.

    Since we have a trick for doing truly private functions (with closures), I consider any class that implements private method with a leading underscore to be broken. If it's a protected method, it should be documented for the benifit of subclasses (away from the public interface documentation, please).

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

      I would argue that if the base methods are truly private, they should have been implemented as lexically scoped closures (declare my $init = sub { }; at the top of the package), not as a regular subroutine.

      (Niggle: Making a subroutine lexically scoped doesn't mean it is a closure.)

      Since most of the time all you want with a private method is to prevent subclasses breaking because they override it, there are a couple of other ways of protecting yourself without using anonymous subroutines.

      package Foo; sub _my_private_method { ... }; # we can just call it as a subroutine, then no matter # what methods the subclass define we're okay. sub my_public_method1 { my $self = shift; ... _my_private_method($self); ... }; # We can also root the method call in the current # class sub my_public_method2 { my $self = shift; ... $self->Foo::_my_private_method; ... };
      It'd be nice if we could do away with the _subroutine_name idiom all together, but Perl doesn't currently provide a way to do protected methods (except by doing some fooling around with caller and isa, and even then it's only a runtime error), so the leading-underscore trick is the next best option.

      I've never come across people using the _method_name convention to indicate protected methods. Since most people use it to indicate private/implementation subroutines I'd probably consider it bad style myself.

      However, since I tend to find protected methods to be a bit of a code smell anyway I don't really care :-)