Как наследовать подпрограммы в Perl с помощью "базы использования"?

Как применить "использовать базу" в Perl для наследования субтитров из некоторого базового модуля?

Я привык к механике наследования С++, и все сайты, которые я искал для этого, вызвали больше путаницы, а затем помогли. Я хочу сделать что-то вроде следующего:

#! /usr/bin/perl
#The base class to inherit from
use strict;
use warnings;

package 'TestBase';

#-------------------------------
sub tbSub
{
    my ($self, $parm) = @_;
    print "\nTestBase: $parm\n";
}

1;

.

#! /usr/bin/perl
#The descendent class
use strict;
use warnings;

use base qw(TestBase);
sub main;
sub mySub;

#-------------------------------
#Entry point...
main();

#---code------------------------
sub main
{
    mySub(1);
    tbSub(2);
    mySub(3);
}

#-------------------------------
sub mySub
{
    my $parm = shift;
    print "\nTester: $parm\n";
}

Perl жалуется/не может найти tbSub.

Ответы

Ответ 1

Механизмы С++ не сильно отличаются от механики Perl: для использования наследования вам нужны два класса: базовый класс и наследующий класс. Но у вас нет класса потомков.

Вам также не хватает конструктора. В отличие от С++, Perl не предоставит вам конструктор по умолчанию.

В базовом классе содержится неверная синтаксическая ошибка, поэтому, думаю, вы не пробовали код перед публикацией.

Наконец, как уже было отмечено, вам нужно будет сообщить Perl, хотите ли вы вызов функции или вызов метода.

То, что вы действительно хотите, будет выглядеть примерно так:

my $foo = TestDescendent->new();
$foo->main();


package TestBase;

sub new {
   my $class = shift;
   return bless {}, $class;
}

sub tbSub
{
   my ($self, $parm) = @_;
   print "\nTestBase: $parm\n";
}

package TestDescendent;
use base 'TestBase';

sub main {
    my $self = shift;
    $self->mySub( 1 );
    $self->tbSub( 2 );
    $self->mySub( 3 );
}

sub mySub
{
    my $self = shift;
    my $parm = shift;
    print "\nTester: $parm\n";
}

1;

Ответ 2

Вы должны взглянуть на Moose, который является системой постмодерна для Perl5. Вероятно, вам будет гораздо легче понять, чем использовать стандартную семантику Perl OO... особенно при переходе с другого языка OO.

Здесь Moose версия вашего вопроса....

package TestBase;
use Moose;

sub tbSub {
   my ($self, $parm) = @_;
   print "\nTestBase: $parm\n";
}


package TestDescendent;
use Moose;
extends 'TestBase';

sub main {
    my $self = shift;
    $self->mySub( 1 );
    $self->tbSub( 2 );
    $self->mySub( 3 );
}

sub mySub {
    my ($self, $parm) = @_;
    print "\nTester: $parm\n";
}


package main;
my $foo = TestDescendent->new();
$foo->main

Различия...

  • Конструктор автоматически создан для вас и
  • Наследование определяется командой "extends" вместо "use base".

Таким образом, этот пример охватывает только кончик айсберга в Музее, -)

Ответ 3

Мне кажется, вы смешиваете две вещи здесь: объектно-ориентированный и процедурный Perl. Perl OO является своеобразным "другим" (как в не основной, так и работоспособной).

Ваш модуль TestBase.pm, похоже, будет запущен как объект Perl (Perl oo-style), но ваш Perl script хочет получить к нему доступ как "нормальный" модуль. Perl не работает так, как это делает С++ (как вы поняли), поэтому вам придется строить свой код по-разному. См. Книги Дамиана Конвей для объяснений (и более разумный код, чем мой ниже).


Процессуальное:

#! /usr/bin/perl
#The module to inherit from

package TestBase;
  use strict;
  use warnings;

  use Exporter ();
  our @ISA         = qw (Exporter);
  our @EXPORT      = qw (tbSub);

#-------------------------------
sub tbSub
{
    my ($parm) = @_;
    print "\nTestBase: $parm\n";
}

1;

.

#! /usr/bin/perl
#The descendent class
use strict;
use warnings;

use TestBase; 
sub main;
sub mySub;

#-------------------------------
#Entry point...
main();

#---code------------------------
sub main
{

    mySub(1);
    tbSub(2);
    mySub(3);
}

#-------------------------------
sub mySub
{
    my $parm = shift;
    print "\nTester: $parm\n";
}

Perl OO

#! /usr/bin/perl
#The base class to inherit from

package TestBase;
  use strict;
  use warnings;

#-------------------------------
sub new { my $s={ };
    return bless $s;
}
sub tbSub
{
    my ($self,$parm) = @_;
    print "\nTestBase: $parm\n";
}

1;

.

#! /usr/bin/perl
#The descendent class
use strict;
use warnings;

use TestBase; 
sub main;
sub mySub;

#-------------------------------
#Entry point...
main();

#---code------------------------
sub main
{
    my $tb = TestBase->new();
    mySub(1);
    $tb->tbSub(2);
    mySub(3);
}

#-------------------------------
sub mySub
{
    my $parm = shift;
    print "\nTester: $parm\n";
}

Ответ 4

Как побочный элемент, для use base нет веской причины, а не более нового use parent.

Ответ 5

Наследование Perl наследует методы, а не функции. Это означает, что вам нужно будет позвонить

main->tbSub(2);

Однако вы действительно хотите наследовать метод в класс:

package Derived;
use base "TestBase";

package main;
Derived->somemethod("foo");

Методы вызова в текущем пакете как функции не будут передаваться в объекте $self или "this" или имени класса магически. Внутри

Class->somemethod("foo")

по существу заканчивается тем, что называется

Class::somemethod("Class", "foo")

внутри. Конечно, это предполагает, что у класса есть подпрограмма/метод с именем "somemethod". Если нет, суперклассы класса будут проверяться, и если у них также нет метода "somemethod", вы получите фатальную ошибку. (Такая же логика применяется для метода $obj- > ( "foo" ).)

Ответ 6

Синтаксис OO использует оператор -> для разделения сообщения и аргументов получателя сообщения. Краткая иллюстрация ниже.

You->do_something( @params );

OR 

$you->do_something( @params );

package A;

sub do_neat_thing { 
    my ( $class_or_instance, @args ) = @_;
    my $class = ref( $class_or_instance );
    if ( $class ) {
         say "Instance of '$class' does a neat thing.";
    }
    else { 
        say "$class_or_instance does a neat thing.";
    }
}

...
package main;
A->do_neat_thing();      # A does a neat thing.
my $a_obj = A->new();
$a_obj->do_neat_thing();     # Instance of 'A' does a neat thing.