Импорт модуля из глобальной области в Perl - PullRequest
0 голосов
/ 01 февраля 2019

Итак, я пытаюсь импортировать модуль в пакет Perl и стараюсь сделать его максимально чистым способом.Сначала я читаю некоторые из предыдущих тем (например: ссылка ).

Модуль находится по следующему пути: /p/disk/tools/perl/5.26.1/lib64/site_perl.Модуль Data::TreeDumper.

Я использовал модуль FindBin для его импорта:

BEGIN {
    use Exporter ();
    use vars qw(@ISA @EXPORT_OK  %EXPORT_TAGS);
    use FindBin;
    use lib "$FindBin::RealBin";
    use lib "$FindBin::Bin";
    use lib "$FindBin::Bin/../lib";
    use lib "/p/disk/tools/perl/5.26.1/lib64/site_perl";
    @ISA       = qw(Exporter);
    @EXPORT_OK = qw(# ALL subs
                   );
    %EXPORT_TAGS = (all => [@EXPORT_OK]);
}
use constants qw(:all);
use Data::TreeDumper;

Он работает для меня, но путь жестко закодирован.Я хотел бы включить путь в пакет constants (мой пакет).Но это своего рода круг, потому что для использования констант (и пути) мне нужно сначала импортировать их, а потом откуда?хах.

Поэтому я подумал удалить строку use lib "/p/disk/tools/perl/5.26.1/lib64/site_perl"; и каким-то образом импортировать сначала файл constants, а затем сделать что-то вроде:

use constants qw(:all);
use lib $PATH_TO_THE_MODULE; # represents path to the module area
use Data::TreeDumper;

Но это не работает.Можно ли этого добиться?

Прежде чем пытаться импортировать модуль (не знал, что он был установлен в глобальном месте), я установил его локально, и он работал.Но я предпочитаю не хранить не мои модули в той же директории, что и проект.Поэтому ИТ-специалисты установили модуль в глобальной области, и я просто спросил, можно ли импортировать его чистым способом.

РЕДАКТИРОВАТЬ: Я пытаюсь вставить путь /p/disk/tools/perl/5.26.1/lib64/site_perl в файл констант в глобальной переменной (назовем это $PATH_TO_THE_MODULE).Затем я хочу импортировать из другого пакета пакет constants, поэтому я использую FindBin.И затем я хочу импортировать модуль, используя переменную $PATH_TO_THE_MODULE, которая указывает на область модуля.Так это должно выглядеть примерно так:

use constants qw(:all);
use lib $PATH_TO_THE_MODULE; # represents a path to the module area
use Data::TreeDumper;

Но это не работает.Я попытался переключиться на require, потому что понял, что require будет использоваться динамически.Но он также не работает с Can't locate Data/TreeDumper.pm in @INC.

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

package test;
$|=1;
use strict;
use warnings;
BEGIN {
    use Exporter ();
    use vars qw(@ISA @EXPORT_OK  %EXPORT_TAGS);
    use FindBin;
    use lib "$FindBin::RealBin";
    use lib "$FindBin::Bin";
    use lib "$FindBin::Bin/../lib";
    @ISA       = qw(Exporter);
    @EXPORT_OK = qw(# ALL subs
                   );
    %EXPORT_TAGS = (all => [@EXPORT_OK]);
}
use constants qw(:all);
use lib $PATH_TO_THE_MODULE; # represents a path to the module area
use Data::TreeDumper;
print "Hi\n";

пакет констант:

package constants;
$|=1;
use strict;
use warnings;
BEGIN {
    use Exporter ();
    use vars qw(@ISA @EXPORT_OK  %EXPORT_TAGS);
    use FindBin;
    use lib "$FindBin::RealBin";
    use lib "$FindBin::Bin";
    use lib "$FindBin::Bin/../lib";
    @ISA       = qw(Exporter);
    @EXPORT_OK = qw($PATH_TO_THE_MODULE);
    %EXPORT_TAGS = (all => [@EXPORT_OK]);
}
our $PATH_TO_THE_MODULE = "/p/disk/tools/perl/5.26.1/lib64/site_perl";

Если я 'Я удалю use lib $PATH_TO_THE_MODULE; и use Data::TreeDumper; из пакета test, и я напечатаю $PATH_TO_THE_MODULE, он скомпилирует и напечатает путь, как и ожидалось.

1 Ответ

0 голосов
/ 03 февраля 2019

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

Ну, ваш код работает, и это потому, что нет ни одной компиляциифаза и фаза одиночного запуска.

Допустим, у вас был следующий скрипт:

use constants ':all';
use lib $PATH_TO_THE_MODULE;
use Data::TreeDumper qw();
print "Hi\n";

И давайте упростим ваш модуль до следующего:

package constants;
use Exporter qw( import );
our @EXPORT_OK = qw( $PATH_TO_THE_MODULE );
our %EXPORT_TAGS = ( all => \@EXPORT_OK );
our $PATH_TO_THE_MODULE = "/path/to/site_perl";

Сохранение вИмейте в виду, что use Foo; примерно эквивалентен BEGIN { use Foo; import Foo; } и что блоки BEGIN выполняются сразу после их компиляции, ниже описывается, что происходит при выполнении сценария:

  1. Compile script.pl
    1. Компиляция use constants ':all';
    2. Выполнение require constants;
      1. Компиляция constants.pm
        1. Компиляция package constants;
        2. Компиляция use Exporter qw( import );
          1. Выполнить require Exporter;
            1. Скомпилировать Exporter.pm [...]
            2. Выполнить Exporter.pm [...]
          2. Выполнить import Exporter qw( import );
        3. Компилировать our @EXPORT_OK = qw( $PATH_TO_THE_MODULE );
        4. Компилировать our %EXPORT_TAGS = ( all => \@EXPORT_OK );
        5. Компилировать our $PATH_TO_THE_MODULE = "/path/to/site_perl";
      2. Выполнить constants.pm
        1. Выполнить our @EXPORT_OK = qw( $PATH_TO_THE_MODULE );
        2. Выполнить our %EXPORT_TAGS = ( all => \@EXPORT_OK );
        3. Выполнить our $PATH_TO_THE_MODULE = "/path/to/site_perl";
    3. Выполнить import constants;
    4. Компиляция use lib $PATH_TO_THE_MODULE;
    5. Выполнение require lib;
      1. Компиляция lib.pm [...]
      2. Выполнение lib.pm [...]
    6. Выполнить import lib $PATH_TO_MODULE;
    7. Компилировать use Data::TreeDumper qw();
    8. Выполнить require Data::TreeDumper;
      1. Компилировать Data/TreeDumper.pm [...]
      2. Выполнить Data/TreeDumper.pm [...]
    9. Компилировать print "Hi\n";
  2. Выполнить script.pl
    1. Выполнить print "Hi\n";

Из вышесказанного мы видим следующее:

  1. [1.2.1.5] $constants::PATH_TO_THE_MODULE isсоздал
  2. [1.2.2.3] $constants::PATH_TO_THE_MODULE задан путь
  3. [1.3] $main::PATH_TO_THE_MODULE создан как псевдоним $constants::PATH_TO_THE_MODULE
  4. [1.6]$main::PATH_TO_THE_MODULE добавлено к @INC
  5. [1.8] Data :: TreeDumper загружен

Забавно, что вы утверждаете, что работает только один из следующих фрагментов идругой нет, когда они в основном сэмe:

use FindBin qw( $RealBin );
use lib $RealBin;

use constants qw( $PATH_TO_THE_MODULE );
use lib $PATH_TO_THE_MODULE;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...