inheritance

Peter Scott Peter at PSDT.com
Sat Feb 22 19:27:44 CST 2003


At 06:59 PM 2/21/03 -0800, Darren Duncan wrote:
>On Thu, 20 Feb 2003, Peter Scott wrote:
> > >sub new {
> > >         my $self = SUPER::new(@_);  # puts blessed hash in $self
> >
> > Hmm, and here all the time I've been doing
> >
> >          my $class = shift;
> >          my $self = $class->SUPER::new(@_);
> >
> > Are you sure that with your approach it will go up the inheritance tree
> > if it doesn't find new() in the first superclass?  I thought you needed
> > a -> method call for that.
>
>You could be right.

I am:

$ cat foo
#!/usr/bin/perl -wl
use strict;

package Top;
sub foo {
   print "Top: @_";
}

package Middle;
use base 'Top';

package Bottom;
use base 'Middle';
sub foo {
   my $class = shift;
   $class->SUPER::foo(@_);
}

sub bar {
   SUPER::foo(@_);
}

package main;
Bottom->foo(1,2,3);
Bottom->bar(1,2,3);

$ ./foo
Top: Bottom 1 2 3
Undefined subroutine &SUPER::foo called at ./foo line 21.


>My previous email answer was strictly from memory.
>This time, I actually looked up some code I did before.  The following is
>part of the source of CGI::Portable or its helper classes.  A convention
>that I have always followed, which makes subclassing easier, is that my
>new() is totally generic, and I do the class-specific work in a separate
>initialize(); the latter is a normal method (except that it can't return
>anything), and is called by new().  Below are examples of
>new()/initialize() from 3 classes related through interitence.
>
>This is from CGI::Portable::Errors, which does not inherit anything, and
>it has properties:
>
>sub new {
>         my $class = shift( @_ );
>         my $self = bless( {}, ref($class) || $class );
>         $self->initialize( @_ );
>         return( $self );
>}
>
>sub initialize {
>         my ($self) = @_;
>
>         $self->{$KEY_ERRORS} = [];
>}

I like this.

>This is from CGI::Portable::Files, which has single inheritence from
>CGI::Portable::Errors, and adds new properties:
>
># sub new {}
># We simply inherit this method and add no new functionality ourself.
>
>sub initialize {
>         my ($self) = @_;
>
>         $self->SUPER::initialize();
>
>         $self->{$KEY_FILE_PATH} = File::VirtualPath->new();
>         $self->{$KEY_PREFS} = {};
>}
>
>This is from CGI::Portable, which has multiple inheritence from
>CGI::Portable::[Files,Request,Response], and adds new properties:
>
>sub new {
>         my $class = shift( @_ );
>         my $self = bless( {}, ref($class) || $class );
>         $self->initialize( @_ );
>         return( $self );
>}
>
>sub initialize {
>         my ($self, $file_root, $file_delim, $prefs) = @_;
>
>         $self->CGI::Portable::Files::initialize();
>         $self->CGI::Portable::Request::initialize();
>         $self->CGI::Portable::Response::initialize();

Yeah, would have been nice if it called all those without having to be 
listed, wouldn't it?  I think NEXT.pm is the official solution 
there.  Have you used it?

--
Peter Scott
Pacific Systems Design Technologies
http://www.perldebugged.com/




More information about the Victoria-pm mailing list