What is the correct way to call the base constructor from the class constructor in Perl ?
I have seen syntax like this:
my $class = shift;
my $a = sh
This problem is why some people recommend not doing anything interesting in your new
method.
new
is expected to create and return a blessed reference, it's hard to make a system that handle doing this twice for the same object from different parent classes.
A cleaner option is to have a new method that only creates the object and calls another method that can set up the object. This second method can behave in a way that allows multiple parent methods to be called. Effectively new
is you allocator and this other method is your constructor.
package Mother;
use strict;
use warnings;
sub new {
my ($class, @args) = @_;
my $self = bless {}, $class;
return $self->_init(@args);
}
sub _init {
my ($self, @args) = @_;
# do something
return $self;
}
package Father;
use strict;
use warnings;
sub new {
my ($class, @args) = @_;
my $self = bless {}, $class;
return $self->_init(@args);
}
sub _init {
my ($self, @args) = @_;
# do something else
return $self;
}
package Child;
use strict;
use warnings;
use base qw(Mother Father);
sub _init {
my ($self, @args) = @_;
# do any thing that needs to be done before calling base classes
$self->Mother::_init(@args); # Call Mother::_init explicitly, SUPER::_init would also call Mother::_init
$self->Father::_init(@args); # Call Father::_init explicitly, SUPER::_init would NOT call Father::_init
# do any thing that needs to be done after calling base classes
return $self;
}
Ether is right about the complications your likely to find by using multiple inheritance. You still need to know that Father::_init
won't override any decisions made by Mother::_init
to start with. It will only get more complicated and harder to debug from there.
I would second the recommendation of Moose, its interface includes a better separation of the object creation and initialization than my example above that usually just works.