2016-09-07 5 views
0

я два модуля Perl onee.pm и two.pm и один Perl script.Following является one.pmНаследование в Perl показывает ошибку в моем случае

package one; 
sub foo 
{ 
print "this is one\n"; 
} 
sub goo 
{ 
print "This is two\n"; 
} 
1; 

two.pm

package two; 
use one; 
@ISA=(one); 
sub hoo 
{ 
    print "this is three \n"; 
} 
1; 

inherit.pl

use two; 
foo(); 

, когда я исполняю inherit.pl я получаю следующее сообщение об ошибке.

Undefined subroutine &main::foo called at inherit.pl line 2. 
+0

Возможный дубликат [Как создается Perl @INC? (ака Какие способы повлиять на поиск модулей Perl?)] (http://stackoverflow.com/questions/2526804/how-is-perls-inc-constructed-aka-what-are-all-the -ways-of-impacting-where-pe) – dubes

+1

@dubes Я не согласен с этой оценкой. – simbabque

ответ

4

Наследование работает над объектами. То, что вы пытаетесь сделать, это импортировать, а не наследовать. Я изложил пример наследования и импорта ниже.

Наследование:

One.pm:

package One; 

sub foo { 
    print "this is one\n"; 
} 
1; 

Two.pm:

package Two; 

# Note the use of 'use base ...;'. That means that we'll inherit 
# all functions from the package we're calling it on. We can override 
# any inherited methods by re-defining them if we need/want 

use base 'One'; 

sub new { 
    return bless {}, shift; 
} 
1; 

inherit.pl:

use warnings; 
use strict; 

use Two; 

my $obj = Two->new; 
$obj->foo; 

Импорт:

One.pm:

package One; 

use Exporter qw(import); 
our @EXPORT_OK = qw(foo); # allow user to import the 'foo' function if desired 

sub foo { 
    print "this is one\n"; 
} 
1; 

Two.pm:

package Two; 
use One qw(foo); # import foo() from One 

use Exporter qw(import); 
our @EXPORT_OK = qw(foo); # re-export it so users of Two can import it 

1; 

import.pl:

use warnings; 
use strict; 

use Two qw(foo); 

foo(); 

Обратите внимание, что в следующем Perl версии (5,26.0), @INC не будет включать текущий рабочий каталог по умолчанию, поэтому до use One; или use Two;, если эти файлы модулей находятся в локальном каталоге, вам нужно будет добавить use lib '.'; или unshift @INC, '.'; или тому подобное.

+1

Благодарим вас за объяснение наследования и импорта –

3

Наследование не имеет к этому никакого отношения. Вы ничего не экспортируете, поэтому подпрограмма foo не находится в пространстве имен вашего сценария.

Фактически вы также смешиваете объектно-ориентированные концепции (наследование) и классические модули Perl. Если у вас есть не-oop-модуль, вы можете иметь экспортера и приводить субтитры в свой скрипт. Если у вас есть класс, вы можете наследовать его из другого класса. Но тогда вы обычно ничего не экспортируете.

Теперь, если вы хотите использовать two импортировать что-то из one, по существу, построить что-то вроде сборника общих функций, вам нужно будет использовать Exporter в one, затем use one в two, а затем использовать Exporter в two для экспортировать функции, импортированные из one.

Звучит сложно? Это происходит потому, что это сложно. Нет никакой реальной выгоды от этого, если не сохранить одну строку из use one в вашем скрипте.

+0

Вещи, которые вы сказали, работают в моем случае thankyou –