2008-10-08 5 views
44

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

Если я

use '../Foo.pm'; 

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

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

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

и .. по-видимому, не обнаруживается в @INC

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

ответ

81

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; 
+1

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

+0

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

+0

Существует также PERL5LIB и ключ -I, как упоминает Брайан. – Axeman

2

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

+1

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

+0

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

6

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

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

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

19

Существует несколько способов изменения @INC.

  • набор PERL5LIB, как описано в perlrun

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

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

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

11

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

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

И тогда, когда я использую их:

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

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

push @array => $pushee; 

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

+2

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

+0

@StevenLu Из ['perldoc perlop'] (http://perldoc.perl.org/perlop.html # Comma-Operator): * «Оператор' => 'является синонимом для запятой, за исключением того, что он вызывает слово слева, чтобы интерпретировать его как строку, если он начинается с буквы или подчеркивания и состоит только из букв , цифры и символы подчеркивания. [...] В противном случае оператор '=>' ведет себя точно так же, как разделитель аргументов запятой или списка в соответствии с контекстом. "*' => 'также известен как« жирная запятая ». – ThisSuitIsBlackNot

+0

Слишком плохо то же самое не для '<='. –

1

Как сообщает "perldoc -f использование":

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

Полагая, что другой путь, «использование» эквивалентно:

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

Таким образом, вместо вызова использования, вы можете позвонить и потребовать импорта Внутри НАЧАТЬ блок:

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^