Your constructor method overrides the constructor of a parent class. You want your constructor to call the parent class's constructor.
Learn about the special class, SUPER.
sub meth { my $self = shift; $self->SUPER::
meth()
; }
In languages like C++ where constructors don't actually allocate memory but just initialize the object, all base class constructors are automatically called for you. In languages like Java and Perl, you have to call them yourself.
To call a method in a particular class, the notation
$self->SUPER::meth()
is used. This is an extension of the regular notation to start looking in a particular base class. It is only valid from within an overridden method. Here's a comparison of styles:
$self->meth();
# Call wherever first meth is found $self->Where::meth();
# Start looking in package "Where" $self->SUPER::meth();
# Call overridden version
Simple users of the class should probably limit themselves to the first one. The second is possible, but not suggested. The last must only be called from within the overridden method.
An overriding constructor should call its SUPER's constructor to allocate and bless the object, limiting itself to instantiating any data fields needed. It makes sense here to separate the object allocation code from the object initialization code. We'll name it with a leading underscore, a convention indicating a nominally private method. Think of it as a "Do Not Disturb" sign.
sub new { my $classname = shift; # What class are we constructing? my $self = $classname->SUPER::new(@_); $self->_init(@_); return $self; # And give it back } sub _init { my $self = shift; $self->{START} = time(); # init data fields $self->{AGE} = 0; $self->{EXTRA} = { @_ }; # anything extra }
Both
SUPER::new
and
_init
have been called with any remaining arguments. That way the user might pass other field initializers in, as in:
$obj = Widget->new( haircolor => red, freckles => 121 );
Whether you store these user parameters in their own extra hash or not is up to you.
Note that SUPER only works on the first overridden method. If your
@ISA
array has several classes, it only gets the first one. A manual traversal of
@ISA
is possible, but probably not worth the hassle.
my $self = bless {}, $class; for my $class (@ISA) { my $meth = $class . "::_init"; $self->$meth(@_) if $class->can("_init"); }
This fragile code assumes that all superclasses initialize their objects with
_init
instead of initializing in the constructor. It also assumes that a hash reference is used for the underlying object.
The discussion on the SUPER class in perltoot (1) and perlobj (1), and in the section on "Method Invocation" in Chapter 5 of Programming Perl
Copyright © 2001 O'Reilly & Associates. All rights reserved.