Manidip Sengupta Manidip Sengupta - 6 months ago 14
Perl Question

What is the preferred convention for Perl Inheritance

In the example below, I have 3 different syntax/mechanisms for defining inheritance. All of them work. Can someone tell me which one is preferred and why (yes, I know "there is more than ..."). Also, why do I need "use WB" in 1 case and not the other 2. TIA

The main -

#!/usr/local/bin/perl -w
#######################

use strict;
use River;
use Ocean;
use Lake;

my $pName = $0; $pName =~ s/.*\///; $pName =~ s/\.\w+$//;

my @sources = (Ocean->new ('Pacific', 1),
River->new ('Brazos', 0),
Lake->new ('Tahoe', 0) );
foreach (@sources) {
$_->printIfSaline ($pName);
}


The modules (Lake, River and Ocean inherit from WaterBody):

######################
# File: Lake.pm
######################

package Lake;

use strict;
use WaterBody;
our @ISA = ('WaterBody');

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

sub printIfSaline {
my ($self, $prompt) = @_;
my $name = $self->getName();
my $taste = $self->isSaline() ? "salty" : "sweet";
print "$prompt: Lake $name has $taste water\n";
}

1

######################
# File: Ocean.pm
######################

package Ocean;

use strict;
use parent 'WaterBody';

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

sub printIfSaline {
my ($self, $prompt) = @_;
my $name = $self->getName;
my $taste = $self->SUPER::isSaline() ? "salty" : "sweet";
print "$prompt: $name Ocean has $taste water\n";
}

1

######################
# File: River.pm
######################

package River;

use strict;
use base 'WaterBody';

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

sub printIfSaline {
my ($self, $prompt) = @_;
my $name = $self->getName;
my $taste = $self->isSaline ? "salty" : "sweet";
print "$prompt: $name river has $taste water\n";
}

1

######################
# File: WaterBody.pm
######################

package WaterBody;

sub new {
my $class = shift;
my $self = {};
$self->{name} = shift;
$self->{saline} = shift;
bless $self, $class;
return $self;
}

sub getName {
my ($self) = @_;
$self->{name}
}

sub isSaline {
my ($self) = @_;
$self->{saline}
}

1

Answer

The use parent pragma sets up the @ISA at compile time. From parent

Establish an ISA relationship with base classes at compile time

When you use ParentClass; and then manually set up @ISA that happens at run time. In this case code in BEGIN, CHECK, or INIT blocks won't be able to use the inheritance hierarchy without extra work.

The use base pragma is older and parent is recommended in docs. From base

Unless you are using the fields pragma, consider this module discouraged in favor of the lighter-weight parent

Thus I'd say go with use parent.