1

I am new to Perl inheritance and haven't been able to find explicit instructions for inheriting the parent constructor. I assumed that all methods (including the constructor) from the parent class are inherited but it appears that this isn't the case. So, this is not enough:

package Child;
use strict;
use Parent;
our @ISA=qw(Parent);

Instead, I need to add a constructor that calls the parent constructor:

package Child;
use strict;
use Parent;
our @ISA=qw(Parent);

sub new {
  my $self=Parent::new(shift);
  bless $self;
  return $self;
}

Perhaps somebody can clarify the logic for me and tell me if the parent constructor be inherited without doing what I did above (explicit declaration and calling the parent constructor)?

slaw
  • 6,591
  • 16
  • 56
  • 109
  • Isn't "new" just another method, and used as constructor only as a convention? – Murali VP Feb 19 '14 at 15:28
  • 1
    if you are using a case-insensitive filesystem, you are going to have a conflict between your `Parent` and the `parent` pragma. – ysth Feb 19 '14 at 15:41
  • `base.pm` still exists, and is still distributed with Perl, but it's not especially recommended. It has a lot of cruft built into it which deals with the `fields` pragma that nobody really uses. – tobyink Feb 19 '14 at 17:09
  • @mpapac: http://stackoverflow.com/a/876578/17389 – ysth Feb 19 '14 at 17:11

3 Answers3

6

You do not need to do that; something is wrong somewhere else in your code.

This is a full working example:

main.pl:

use strict;
use warnings;
use Subclass;
my $object = Subclass->new();
print "object is a ", ref $object, "\n";

Subclass.pm:

package Subclass;
use strict;
use warnings;
use parent 'Superclass';
1;

Superclass.pm:

package Superclass;
use strict;
use warnings;
sub new {
    my $class = $_[0];
    return bless {}, $class;
}
1;

use parent 'Superclass' just loads Superclass and sets @ISA for you.

ysth
  • 96,171
  • 6
  • 121
  • 214
0

As per @ysth's answer, you shouldn't need to override the parent constructor unless you need to do something special in your constructor. In which case, the way you'd usually do it would be like this:

sub new {
   my $class = shift;
   my $self  = $class->SUPER::new(@_);
   ...;
   return $self;
}

At a guess, the reason inheritance is not working properly is that you might be using the one argument form of bless in the superclass. Something like this:

bless $self;

Except in very unusual circumstances, you should always prefer the two-argument version of bless:

bless $self, $class;

Where $class is the first argument passed to the new sub.

tobyink
  • 13,478
  • 1
  • 23
  • 35
-1

Often, if you want a constructor for one class to call the parent class, this will be handled by the "psuedo-class" SUPER.

package Derived;
use parent 'Base';

sub new { 
    my $class_name = shift;
    my $self       = $class_name->SUPER::new( @_ );

    return init_Derived( $self );
}

This will only work with single descent. With multiple parents, you have to bash it together yourself.

Axeman
  • 29,660
  • 2
  • 47
  • 102