inheritance

Darren Duncan darren at DarrenDuncan.net
Fri Feb 21 20:59:40 CST 2003


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.  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} = [];
}

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();

	$self->{$KEY_IS_DEBUG} = undef;

	$self->{$KEY_PREF_APIT} = 'Untitled Application';
	$self->{$KEY_PREF_MNAM} = 'Webmaster';
	$self->{$KEY_PREF_MEAD} = 'webmaster at localhost';
	$self->{$KEY_PREF_MESP} = undef;
	$self->{$KEY_PREF_SMTP} = 'localhost';
	$self->{$KEY_PREF_TIME} = '30';

	$self->{$KEY_MISC_OBJECTS} = {};

	$self->file_path_root( $file_root );
	$self->file_path_delimiter( $file_delim );
	$self->set_prefs( $prefs );
}

I suppose in retrospect that CGI::Portable didn't need to declare its own
new(), since no matter which of its parent classes would have been called,
any would have worked anyway.  Perhaps I will remove this in an update.

Hopefully those examples are helpful.  It shows the range that I have
actually seen working.

-- Darren Duncan




More information about the Victoria-pm mailing list