Как построен Perl's @INC? (ака, каковы все способы влияния на то, где ищут модули Perl?)
каковы все способы влияния на поиск модулей Perl? или, Как построен Perl's @INC?
Как известно, Perl использует @INC
массив, содержащий имена каталогов, чтобы определить, где искать файлы модуль Perl.
Кажется, что нет всеобъемлющего сообщения типа FAQ" @INC " на StackOverflow, поэтому этот вопрос предназначен как один.
3 ответов
мы рассмотрим, как содержимое этого массива строится и может манипулировать, чтобы повлиять на то, где интерпретатор Perl найдет файлы модуля.
-
по умолчанию
@INC
Perl интерпретатор скомпилировано с определенным
@INC
значение по умолчанию. Чтобы узнать это значение, запустите (env -i
игнорироватьPERL5LIB
переменная окружающей среды-см. #2), и на выходе вы увидите что-то вроде это:$ env -i perl -V ... @INC: /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/site_perl/5.18.0 /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/5.18.0 .
Примечание .
в конце; это текущий каталог (который не обязательно совпадает с скрипт каталог). Он отсутствует в Perl 5.26+, и когда Perl работает с -T
(проверка заражения включена).
чтобы изменить путь по умолчанию при настройке двоичной компиляции Perl, установите параметр конфигурации otherlibdirs
:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3
-
переменные среды
PERL5LIB
(илиPERLLIB
)Perl pre-pends
@INC
со списком каталогов (разделенных двоеточием), содержащегося вPERL5LIB
(если он не определен,PERLLIB
используется) переменная окружения вашей оболочки. Чтобы увидеть содержимое@INC
послеPERL5LIB
иPERLLIB
переменные среды вступили в силу, запуститеperl -V
.$ perl -V ... %ENV: PERL5LIB="/home/myuser/test" @INC: /home/myuser/test /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/site_perl/5.18.0 /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/5.18.0 .
-
Perl pre-pends
@INC
со списком каталогов (разделенных двоеточием) передается как значение . Это можно сделать тремя способами, как обычно с вариантами Перл:-
передайте его в командной строке:
perl -I /my/moduledir your_script.pl
-
передайте его через первую строку (shebang) вашего Perl сценарий:
#!/usr/local/bin/perl -w -I /my/moduledir
передать его как часть
PERL5OPT
(илиPERLOPT
) переменной окружения (см. главу 19.02 в Программирование На Perl)
-
-
передайте его через
lib
ПРАГМАPerl pre-pends
@INC
со списком каталогов, переданных ему черезuse lib
.в программе:
use lib ("/dir1", "/dir2");
в командной строка:
perl -Mlib=/dir1,/dir2
вы можете удалить каталоги от
@INC
viano lib
. -
вы можете напрямую манипулировать
@INC
как обычный массив Perl.Обратите Внимание:
@INC
используется на этапе компиляции, это должно быть сделано внутриBEGIN {}
блок, который предшествуетuse MyModule
заявление.добавить каталоги в начало через
unshift @INC, $dir
.добавить каталоги до конца через
push @INC, $dir
.сделайте все, что вы можете сделать с массивом Perl.
Примечание: директории unshifted на @INC
в порядке, указанном в этом ответе, например по умолчанию @INC
является последним в списке, перед PERL5LIB
, предшествуют -I
, предшествуют use lib
и направить @INC
манипуляция, последние два смешанные в любом порядке они находятся в коде Perl.
ссылки:
- perldoc perlmod
- perldoc lib
- Perl Module Mechanics-отличное руководство, содержащее практические HOW-TOs
- как "использовать" модуль Perl в каталоге не в
@INC
? - Программирование На Perl - глава 31 часть 13, ch 7.2.41
- как программа Perl знает, где найти файл, содержащий модуль Perl, который она использует?
не представляется всестороннее @INC
FAQ-введите сообщение о переполнении стека, поэтому этот вопрос предназначен как один.
когда использовать каждый подход?
если модули в каталоге должны использоваться многими / всеми скриптами на вашем сайте, особенно запускаемыми несколькими пользователями, этот каталог должен быть включен в значение по умолчанию
@INC
скомпилирован в двоичный файл Perl.-
если модули в каталоге будут использоваться исключительно конкретным пользователем для всех сценариев, которые запускает пользователь (или если перекомпиляция Perl не является возможностью изменить значение по умолчанию
@INC
в предыдущем случае использования), установите пользователейPERL5LIB
, обычно во время входа пользователя.Примечание: обратите внимание на обычные подводные камни переменной среды Unix-например, в некоторых случаях работает скрипты как конкретный пользователь не гарантируют их запуск с настройкой среды этого пользователя, например, через
su
. если модули в каталоге необходимо использовать только в определенных обстоятельствах(например, когда сценарий (ы) выполняется в режиме разработки/отладки, вы можете либо установить
PERL5LIB
вручную, или пройти-I
опция для perl.если модули должны использоваться только для определенных сценариев, по все пользователи, использующие их, используют
use lib
/no lib
прагмы в самой программе. Он также должен использоваться, когда каталог для поиска должен быть динамически определен во время выполнения-например, из параметров командной строки скрипта или пути скрипта (см. FindBin модуль для очень хорошего случая использования).-
если каталоги в
@INC
нужно манипулировать в соответствии с какой-то сложной логикой, либо невозможно тоже громоздкий для реализации комбинациейuse lib
/no lib
прагмы, затем используйте direct@INC
манипуляции внутриBEGIN {}
блок или внутри библиотеки специального назначения, предназначенной для@INC
манипуляция, которая должна использоваться вашим скриптом(сценариями) перед использованием любых других модулей.примером этого является автоматическое переключение между библиотеками в каталогах prod/uat/dev, с подборкой библиотеки waterfall в prod, если она отсутствует в dev и / или UAT (последнее условие делает стандартное решение "использовать lib + FindBin" довольно сложное. Подробная иллюстрация этого сценария находится в как использовать модули beta Perl из сценариев beta Perl?.
дополнительный вариант использования для непосредственного управления
@INC
должен иметь возможность добавлять ссылки на подпрограммы или ссылки на объекты (да, Вирджиния,@INC
может содержать пользовательский код Perl, а не только имена каталогов, как описано в когда ссылка на подпрограмму в @INC называется?).
в дополнение к местоположениям, перечисленным выше, версия OS X Perl также имеет еще два способа:
The / Library / Perl / x.xx / файл AppendToPath. Пути, перечисленные в этом файле, добавляются в @INC во время выполнения.
The / Library / Perl / x.файл xx / PrependToPath. Пути, перечисленные в этом файле, добавляются в @INC во время выполнения.
как уже было сказано, @INC-это массив, и вы можете добавить все, что захотите.
мой скрипт CGI REST выглядит так:
#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
push @INC, 'fully_qualified_path_to_module_wiht_our_REST.pm';
}
use Modules::Rest;
gone(@_);
подпрограмма gone экспортируется Rest.pm.