Как «использовать» модуль Perl в каталоге, а не в @INC? - PullRequest
49 голосов
/ 09 октября 2008

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

Если я делаю

use '../Foo.pm';

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

Я пытался сделать:

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

и .. очевидно не появляется в @ INC

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

Ответы [ 6 ]

88 голосов
/ 09 октября 2008

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;
19 голосов
/ 09 октября 2008

Есть несколько способов изменить @INC.

  • установить PERL5LIB, как описано в perlrun

  • используйте ключ -I в командной строке, также задокументированный в perlrun . Вы также можете применить это автоматически с PERL5OPT, но просто используйте PERL5LIB, если вы собираетесь это сделать.

  • use lib внутри вашей программы, хотя она хрупкая, поскольку другой человек на другом компьютере может иметь ее в другом каталоге.

  • Вручную измените @INC, убедитесь, что вы делаете это во время компиляции, если хотите использовать модуль с использованием. Это слишком много работы.

12 голосов
/ 09 октября 2008

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

/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm

А потом, где я их использую:

use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;

В качестве отступления ... когда дело доходит до толчка, я предпочитаю запятую с толстой стрелой:

push @array => $pushee;

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

6 голосов
/ 09 октября 2008

'use lib' - это ответ, как упоминалось ранее @ephemient. Еще один вариант - использовать require / import вместо использования. Это означает, что модуль будет загружен не во время компиляции, а во время выполнения.

Это позволит вам изменить @INC, как вы пытались там, или вы могли бы указать путь к файлу вместо имени модуля. Из 'perldoc -f require':

Если EXPR - пустое слово, требование предполагает расширение «.pm» и заменяет "::" на "/" в имени файла, чтобы упростить загрузить стандартные модули. Эта форма загрузки модулей не рискует изменяя ваше пространство имен.

2 голосов
/ 09 октября 2008

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

1 голос
/ 21 декабря 2008

Как сообщает "perldoc -f use":

Это в точности эквивалентно
BEGIN { require Module; import Module LIST; }
за исключением того, что модуль должен быть голым словом.

Другими словами, «использование» эквивалентно:

  • работает во время компиляции,
  • преобразование имени пакета в имя файла,
  • require - с этим именем файла и
  • import -ing этот пакет.

Таким образом, вместо вызова use вы можете вызвать require и import внутри блока BEGIN:

BEGIN {
  require '../EPMS.pm';
  EPMS->import();
}

И, конечно, если ваш модуль на самом деле не выполняет экспорт символов или другую инициализацию при вызове import, вы можете не указывать эту строку:

BEGIN {
  require '../EPMS.pm';
}
...