2008-11-03 11 views
14

Как применить «использовать базу» в Perl для наследования субтитров из некоторого базового модуля?Как я могу наследовать подпрограммы в Perl с 'use base'?

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

#! /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.

ответ

20

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

Вам также не нужен конструктор. В отличие от C++, 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; 
4

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

main->tbSub(2); 

Однако то, что вы действительно хотите, чтобы наследовать метод в надлежащий класс:

package Derived; 
use base "TestBase"; 

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

Вызов методов в текущем пакете, как функции не будут проходить в $ self или «этот» объект или имя класса магически. Внутренне

Class->somemethod("foo") 

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

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

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

+0

Нет, это не так называется - оно будет искать иерархию наследования, поэтому может вызвать sub в совершенно другом пакете. Кроме того, ваши примеры не являются допустимым синтаксисом. (Я знаю, что вы пытались сказать, но, как вы сказали, это должно смутить кого-то, как путаницу, как OP еще дальше.) – 2008-11-03 11:57:58

+0

Конечно, он ходит по дереву наследования. В конце концов, вопрос о наследовании. Обратите внимание, что OP используется для использования наследования C++, поэтому я думал, что это будет очевидно. – tsee 2008-11-03 12:51:11

5

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

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


Процедурный:

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

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

+0

Интересно. Но есть ли веские основания использовать родителя? – innaM 2008-11-03 14:53:48

10

Вы должны взглянуть на использование 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 

Различие ....

  • Конструктор автоматически создается для вас &
  • наследования, определенное "распространяется" вместо «использовать базу».

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

1

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

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. 

 Смежные вопросы

  • Нет связанных вопросов^_^