Могут ли perl модули "использовать" другие perl модули? - PullRequest
4 голосов
/ 07 апреля 2020

perl 5.24.0 на linux

Perl проблема "вложения" модуля (вроде) ... Мне кажется, я не могу заставить это работать, и мне было интересно, если кто-то мог Скажи мне, что не так. В приведенном ниже простом примере моя проблема будет сформулирована лучше, чем моя вера ...

Сначала ping.pl ...

#!/usr/bin/env perl
# This is ping.pl

use ping_mod;

ping_dbh();

exit;

Далее следует модуль perl, ping_mod.pm. ...

#!/usr/bin/env perl
use Exporter;
use ping_common;

package ping_mod;

@ISA = qw(Exporter);
@EXPORT = qw(ping_dbh);

sub ping_dbh {
    set_dbh();
    print "dbh = $dbh\n";
}

1;

Наконец, ping_common.pm, который использует ping_mod ...

#!/usr/bin/env perl
use Exporter;

our $dbh;

package ping_common;

@ISA = qw(Exporter);
@EXPORT = qw($dbh set_dbh);

sub set_dbh {
    $dbh = 99;
}

1;

Когда я запускаю ping.pl, я получаю ...

Undefined subroutine &ping_mod::set_dbh called at ping_mod.pm line 11.

Но если я изменю ping_mod.pm на ...

#!/usr/bin/env perl
use Exporter;
use ping_common;

package ping_mod;

@ISA = qw(Exporter);
@EXPORT = qw(ping_dbh);

sub ping_dbh {
#    set_dbh();
#    print "dbh = $dbh\n";
    print "hi there\n";    
}

1;

... он будет работать нормально. Итак, я думаю, что это должно быть экспорт хорошо. Но «использование» ping_common каким-то образом портит его.

Даже если я «использую ping_common» в ping.pl, он все равно не может его найти.

1 Ответ

8 голосов
/ 07 апреля 2020

Как сказал @ tooli c, use ping_common должен быть после оператора package. Вот почему.

Пакеты в Perl изолируют глобальные переменные и функции. Полное название для ping_dbh действительно ping_mod::ping_dbh. Вы можете позвонить ping_dbh в пакете ping_mod. Если вы хотите вызвать его в другом месте, вы должны использовать его полное имя, ping_mod::ping_dbh.

use Module на самом деле require Module для его загрузки и Module->import для импорта его функций и переменных в текущий пакет. Неважно, куда загружен модуль, если он загружен. Но очень важно, где он импортируется.

Имея это в виду, посмотрите на это.

use ping_common;

package ping_mod;

Это загрузит ping_common и импортирует его функции, а не в ping_mod , но в пакет по умолчанию main. Они не будут доступны для ping_mod.

package ping_mod;

use ping_common;

Это также загружает ping_common, но импортирует его функции в ping_mod.

Но почему Exporter по-прежнему работает, даже если вне пакета?

use Exporter;
use ping_common;

package ping_mod;

@ISA = qw(Exporter);
@EXPORT = qw(ping_dbh);

Как ни странно, экспортер не работает при экспорте. Работает по наследству. @ISA = qw(Exporter); заставляет ping_mod наследовать метод import от Exporter. То, что @ISA находится в пакете ping_mod, является глобальной переменной @ping_mod::ISA.


.pm, и файлы обычно должны начинаться с оператора package. Они не должны начинаться с #!; хотя это ничего не повредит. #! сообщает операционной системе, что использовать для запуска файла в качестве исполняемой программы. Модули Perl, как правило, не являются исполняемыми.

Подробнее о пакетах вы можете прочитать в perlmod .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...