简体   繁体   中英

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

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 .

use parent 'Foo::Bar';

is cleanest, although the repetitious

use Foo::Bar qw( );
our @ISA = 'Foo::Bar';

is still commonly used. The former also has the advantage of happening sooner (when the file is compiled) than the latter (when the file is executed), though that rarely matters.

base is discouraged because it silences errors that occur when a module is loaded.

Manipulating @ISA is the oldest way. base was the second way, and parent is even newer. So, I'd recommend parent for new projects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM