Как мне «использовать» модуль Perl в каталоге не в @INC?

У меня есть модуль в родительском каталоге моего скрипта, и я хотел бы его «использовать».

Если я сделаю

use '../Foo.pm';

Я получаю синтаксические ошибки.

Я пробовал делать:

push @INC, '..';
use EPMS;

и .. очевидно, не отображается в @INC

Я схожу с ума! Что здесь не так?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
57
0
71 840
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Вы должны обработать push до того, как будет обработан use, а use будет обработан раньше. Так что, я думаю, вам понадобится BEGIN { push @INC, ".."; }, чтобы получить шанс.

Обычно вы хотите выполнить несдвиг, чтобы каталог находился в начале списка. Таким образом, Perl не нужно искать его во всех @INC. :)

brian d foy 09.10.2008 02:16

Да, это тоже ... Обычно я не использую относительные имена, потому что я обычно не запускаю скрипты из фиксированного каталога, так что ...

Jonathan Leffler 09.10.2008 02:38
Ответ принят как подходящий

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. :)

brian d foy 09.10.2008 02:17

Да, верно, поэтому преобразование BEGIN {push} => use lib тоже не идентично. Но я хотел показать минимальное полезное изменение вопроса, чтобы он заработал. Спасибо, что заметили :)

ephemient 09.10.2008 04:34

Также есть PERL5LIB и переключатель -I, как упоминает Брайан.

Axeman 10.10.2008 09:04

В Windows я могу успешно вызвать этот метод: используйте lib 'D: \ webserver \ sites \ test \ testing'; но не используя, используйте lib '\ testing'; (или используйте lib '.. \ testing'; или используйте lib '. \ testing';). В обоих случаях я запускаю скрипт из тестовой папки. Как сделать относительное именование. Это разница в Linux и Windows.

msinfo 26.01.2014 02:22

'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;

Но это только вопрос предпочтений.

Этот толкающий синтаксис выглядит очень запутанным. Это определенно указывает неверный путь. С механической точки зрения. Это то же самое, что и запятая? Запятая гораздо более неоднозначна в отношении направления и, следовательно, лучше ...

Steven Lu 31.05.2013 19:15

@StevenLu Из perldoc perlop: "Оператор => является синонимом запятой, за исключением того, что он заставляет слово слева от него интерпретироваться как строка, если оно начинается с буквы или подчеркивания и состоит только из букв, цифр и знаков подчеркивания. [...] В противном случае , оператор => ведет себя точно так же, как оператор запятой или разделитель аргументов списка, в зависимости от контекста ".=> также известен как «жирная запятая».

ThisSuitIsBlackNot 03.07.2014 00:42

Жаль, что этого не происходит с <=.

Steven Lu 03.07.2014 15:30

Как сообщает "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.

см. POD для lib :: relative

Другие вопросы по теме