У меня есть модуль в родительском каталоге моего script, и я хотел бы использовать его.
Если я делаю
use '../Foo.pm';
Я получаю синтаксические ошибки.
Я попытался сделать:
push @INC, '..';
use EPMS;
и.., по-видимому, не отображается в @INC
Я схожу с ума! Что здесь не так?
use
выполняется во время компиляции, поэтому это будет работать:
BEGIN {push @INC, '..'}
use EPMS;
Но лучшим решением является use lib
, что является более приятным способом написания выше:
use lib '..';
use EPMS;
Если вы работаете из другого каталога, рекомендуется использовать FindBin
:
use FindBin; # locate this script
use lib "$FindBin::RealBin/.."; # use the parent directory
use EPMS;
Существует несколько способов изменения @INC
.
установить PERL5LIB, как описано в perlrun
используйте ключ -I в командной строке, также задокументированный в perlrun. Вы также можете применить это автоматически с помощью PERL5OPT, но просто используйте PERL5LIB, если вы это сделаете.
use lib
внутри вашей программы, хотя это хрупко, поскольку другой человек на другой машине может иметь его в другом каталоге.
Вручную измените @INC
, убедившись, что вы делаете это во время компиляции, если хотите использовать модуль с использованием. Это слишком много работает.
Лично я предпочитаю хранить свои модули (те, которые я пишу для себя или для систем, которые я могу контролировать) в определенном каталоге, а также размещать их в подкаталоге. Как в:
/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm
И затем, где я их использую:
use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;
В стороне.. когда дело доходит до нажатия, я предпочитаю запятую с жирными стрелками:
push @array => $pushee;
Но это только вопрос предпочтения.
perldoc perlop
: «Оператор =>
является синонимом запятой, за исключением того, что он вызывает слово слева от него, которое интерпретируется как строка, если оно начинается с буквы или подчеркивания и состоит только из букв, цифр и подчеркиваний . [...] В противном случае оператор =>
ведет себя точно так же, как оператор запятой или разделитель аргументов списка, в зависимости от контекста. " =>
также известен как «толстая запятая».
'use lib' - это ответ, как упоминалось ранее. Еще один вариант - использовать require/import вместо использования. Это означает, что модуль не будет загружаться во время компиляции, а вместо этого во время выполнения.
Это позволит вам изменить @INC по мере того, как вы там пытались, или вы можете передать требуемый путь к файлу вместо имени модуля. Из "perldoc -f require":
Если EXPR - это годовое слово, требование предполагает расширение ".pm" и заменяет "::" на "/" в имени файла для вас, чтобы упростить загрузить стандартные модули. Эта форма загрузки модулей не подвержена риску изменяя пространство имен.
Вы должны обработать push
до того, как use
- и use
обрабатывается раньше. Итак, вам понадобится BEGIN { push @INC, ".."; }
, чтобы иметь шанс, я полагаю.
Как указано в "perldoc -f use":
Это точно эквивалентно
BEGIN { require Module; import Module LIST; }
за исключением того, что модуль должен быть гостем.
Другими словами, "использование" эквивалентно:
require
- имя этого файла иimport
-показать этот пакет.Итак, вместо вызова использования вы можете вызвать require и импортировать внутри блока BEGIN:
BEGIN {
require '../EPMS.pm';
EPMS->import();
}
И, конечно, если ваш модуль на самом деле не выполняет экспорт символов или другую инициализацию при вызове импорта, вы можете оставить эту строку:
BEGIN {
require '../EPMS.pm';
}
use lib
преобразования BEGIN {push} =>use lib
не является идентичным. Но я хотел показать минимальное полезное изменение от вопроса, чтобы оно заработало. Спасибо, что заметили :)