Подтвердить что ты не робот

Что является предпочтительным соглашением для Perl Inheritance

В приведенном ниже примере у меня есть 3 разных синтаксиса/механизма для определения наследования. Все они работают. Может ли кто-нибудь сказать мне, какой из них предпочтительнее и почему (да, я знаю "больше..." ). Кроме того, зачем мне "использовать WB" в одном случае, а не в другом. 2. TIA

Основной -

#!/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);
}

Модули (озеро, река и океан наследуются от 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
4b9b3361

Ответ 1

Прагма use parent устанавливает время @ISA во время компиляции. Из parent

Установить связь ISA с базовыми классами во время компиляции

Когда вы use ParentClass;, а затем вручную настроите @ISA, что происходит во время выполнения. В этом случае код в блоках BEGIN, CHECK или INIT не сможет использовать иерархию наследования без дополнительной работы.

Прагма use base старше и parent рекомендуется в документах. Из base

Если вы не используете прагму полей, подумайте, что этот модуль обескуражен в пользу более светлого родителя

Таким образом, я бы сказал, идите с use parent.

Ответ 2

use parent 'Foo::Bar';

является самым чистым, хотя повторяющийся

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

все еще используется. Первое преимущество также имеет то преимущество, что раньше (когда файл скомпилирован) происходит быстрее, чем последний (когда файл выполняется), хотя это редко имеет значение.

База

обескуражена, поскольку она отключает ошибки, возникающие при загрузке модуля.

Ответ 3

Манипуляция @ISA является самым старым способом. base был вторым способом, а parent еще новее. Поэтому я рекомендую parent для новых проектов.