У меня есть модуль в родительском каталоге моего скрипта, и я хотел бы его «использовать».
Если я сделаю
use '../Foo.pm';
Я получаю синтаксические ошибки.
Я пробовал делать:
push @INC, '..';
use EPMS;
и .. очевидно, не отображается в @INC
Я схожу с ума! Что здесь не так?





Вы должны обработать push до того, как будет обработан use, а use будет обработан раньше. Так что, я думаю, вам понадобится BEGIN { push @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;
Обычно вы хотите выполнить несдвиг, чтобы каталог находился в начале списка. Таким образом, Perl не нужно искать его во всех @INC. :)
Да, верно, поэтому преобразование BEGIN {push} => use lib тоже не идентично. Но я хотел показать минимальное полезное изменение вопроса, чтобы он заработал. Спасибо, что заметили :)
Также есть PERL5LIB и переключатель -I, как упоминает Брайан.
В Windows я могу успешно вызвать этот метод: используйте lib 'D: \ webserver \ sites \ test \ testing'; но не используя, используйте lib '\ testing'; (или используйте lib '.. \ testing'; или используйте lib '. \ testing';). В обоих случаях я запускаю скрипт из тестовой папки. Как сделать относительное именование. Это разница в Linux и Windows.
'use lib' - это ответ, как упоминалось ранее в @ephemient. Еще один вариант - использовать require / import вместо use. Это означает, что модуль загружается не во время компиляции, а во время выполнения.
Это позволит вам изменить @INC, как вы там пытались, или вы можете передать требуемый путь к файлу вместо имени модуля. Из 'perldoc -f require':
If EXPR is a bareword, the require assumes a ".pm" extension and replaces "::" with "/" in the filename for you, to make it easy to load standard modules. This form of loading of modules does not risk altering your namespace.
Есть несколько способов изменить @INC.
установите PERL5LIB, как описано в Perlrun
используйте переключатель -I в командной строке, также описанный в Perlrun. Вы также можете применить это автоматически с помощью PERL5OPT, но просто используйте PERL5LIB, если вы собираетесь это сделать.
use lib внутри вашей программы, хотя это ненадежно, поскольку другой человек на другой машине может иметь его в другом каталоге.
Вручную измените @INC, убедившись, что вы делаете это во время компиляции, если вы хотите загрузить модуль с помощью use. Однако это слишком много работы.
require имя файла напрямую. Хотя это возможно, это не позволяет этому имени файла загружать файлы в тот же каталог. Это определенно вызовет недоумение при проверке кода.
Лично я предпочитаю хранить свои модули (те, которые я пишу для себя или для систем, которые могу контролировать) в определенном каталоге, а также помещать их в подкаталог. Как в:
/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm
А потом где я их использую:
use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;
В стороне ... когда дело доходит до нажатия, я предпочитаю запятую с жирной стрелкой:
push @array => $pushee;
Но это только вопрос предпочтений.
Этот толкающий синтаксис выглядит очень запутанным. Это определенно указывает неверный путь. С механической точки зрения. Это то же самое, что и запятая? Запятая гораздо более неоднозначна в отношении направления и, следовательно, лучше ...
@StevenLu Из perldoc perlop: "Оператор => является синонимом запятой, за исключением того, что он заставляет слово слева от него интерпретироваться как строка, если оно начинается с буквы или подчеркивания и состоит только из букв, цифр и знаков подчеркивания. [...] В противном случае , оператор => ведет себя точно так же, как оператор запятой или разделитель аргументов списка, в зависимости от контекста ".=> также известен как «жирная запятая».
Жаль, что этого не происходит с <=.
Как сообщает "perldoc -f use":
It is exactly equivalent to
BEGIN { require Module; import Module LIST; }
except that Module must be a bareword.
Другими словами, «использование» эквивалентно:
require-ing это имя файла иimport-в этом пакете.Итак, вместо вызова use вы можете вызвать require и import внутри блока BEGIN:
BEGIN {
require '../EPMS.pm';
EPMS->import();
}
И, конечно же, если ваш модуль на самом деле не выполняет экспорт символов или другую инициализацию при вызове импорта, вы можете оставить эту строку вне поля:
BEGIN {
require '../EPMS.pm';
}
Некоторые IDE работают некорректно с предпочтительным ответом "use lib". Я обнаружил, что 'use lib :: relative' работает с моей IDE, JetBrains 'WebStorm.
Обычно вы хотите выполнить несдвиг, чтобы каталог находился в начале списка. Таким образом, Perl не нужно искать его во всех @INC. :)