Calling base constructor in perl

Zitrax picture Zitrax · Mar 9, 2011 · Viewed 9.5k times · Source

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 = shift; 
 my $b = shift;
 my $self = $class->SUPER::new($a, $b);
 return $self;

Is this correct ? What if we have several parent classes. For example a class like this:

 package Gamma;
 use base Alpha;
 use base Beta;

 sub new
 {
   # Call base constructors...
 }
 1;

Answer

Ether picture Ether · Mar 9, 2011

If all your constructor is doing is calling the parent constructor (as in your example, you don't need to write one at all. Simply leave it out and the parent will be called; you just need to ensure that the object is blessed into the right type:

package Parent;
use strict;
use warnings;

sub new
{
    my ($class, @args) = @_;

    # do something with @args

    return bless {}, $class;
}
1;

If you use the above code and have a Child class declared with use parent 'Parent'; then the Parent constructor will properly construct a child.

If you need to add some properties in the Child, then what you had is largely correct:

package Child;
use strict;
use warnings;

use parent 'Parent';

sub new
{
    my ($class, @args) = @_;

    # possibly call Parent->new(@args) first
    my $self = $class->SUPER::new(@args);

    # do something else with @args

    # no need to rebless $self, if the Parent already blessed properly
    return $self;
}
1;

However, when you bring multiple inheritance into the mix, you need to decide the right thing to do at every step of the way. This means a custom constructor for every class that decides how to merge the properties of Parent1 and Parent2 into the child, and then finally blesses the resulting object into the Child class. This complication is one of many reasons why multiple inheritance is a bad design choice. Have you considered redesigning your object heirarchy, possibly by moving some properties into roles? Further, you might want to employ an object framework to take out some of the busy work, such as Moose. Nowadays it is rarely necessary to write a custom constructor.

(Lastly, you should avoid using the variables $a and $b; they are treated differently in Perl as they are the variables used in sort functions and some other built-ins.)