Мы посмотрим, как сконструировано содержимое этого массива, и с его помощью можно повлиять на то, где интерпретатор Perl найдет файлы модуля.
По умолчанию @INC
Perl-интерпретатор компилируется с определенным @INC
значением по умолчанию . Чтобы узнать это значение, запустите env -i perl -V
команду ( 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 предварительно ожидает @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
.
-I
опция командной строки
Perl предварительно ожидает @INC
список каталогов (разделенных двоеточиями), переданных в качестве значения параметра -I
командной строки. Это можно сделать тремя способами, как обычно, с помощью параметров Perl:
Передайте это в командной строке:
perl -I /my/moduledir your_script.pl
Передайте его через первую строку (shebang) вашего скрипта Perl:
#!/usr/local/bin/perl -w -I /my/moduledir
Передайте его как часть PERL5OPT
(или PERLOPT
) переменной окружения (см. Главу 19.02 в Программирование на Perl )
Передайте это через lib
прагму
Perl предварительно ожидает @INC
список каталогов, переданных ему черезuse lib
.
В программе:
use lib ("/dir1", "/dir2");
В командной строке:
perl -Mlib=/dir1,/dir2
Вы также можете удалить каталоги с @INC
помощьюno lib
.
Вы можете напрямую манипулировать @INC
как обычный массив Perl.
Примечание: поскольку @INC
используется на этапе компиляции, это должно быть сделано внутри BEGIN {}
блока, который предшествует use MyModule
оператору.
Добавить каталоги в начало через unshift @INC, $dir
.
Добавить каталоги до конца через push @INC, $dir
.
Сделайте что-нибудь еще, что вы можете сделать с массивом Perl.
Примечание: каталоги сдвинут на @INC
в порядке , указанном в этом ответе, например , по умолчанию @INC
является последним в списке, которым предшествуют PERL5LIB
, которому предшествует -I
, предшествует use lib
и прямой@INC
манипуляции, последние два смешиваться в зависимости от того , заказать их в коде Perl.
Ссылки:
Там не кажется всеобъемлющим @INC
переполнении стека нет поста типа FAQ, поэтому этот вопрос задуман как один.
Когда использовать каждый подход?
Если модули в каталоге должны использоваться многими / всеми сценариями на вашем сайте, особенно выполняемыми несколькими пользователями, этот каталог должен быть включен в стандартный каталог, @INC
скомпилированный в двоичный файл Perl.
Если модули в каталоге будут использоваться исключительно конкретным пользователем для всех сценариев, которые запускает пользователь (или если перекомпиляция Perl не является опцией для изменения значения @INC
по умолчанию в предыдущем случае использования), установите пользователей PERL5LIB
, обычно при входе пользователя в систему.
Примечание: Пожалуйста, имейте в виду обычные подводные камни переменных среды Unix - например, в некоторых случаях запуск сценариев от имени конкретного пользователя не гарантирует запуск их с настройкой среды этого пользователя, например, через su
.
Если модули в каталоге необходимо использовать только при определенных обстоятельствах (например, когда сценарии выполняются в режиме разработки / отладки, вы можете установить их PERL5LIB
вручную или передать -I
параметр perl.
Если модули нужно использовать только для определенных сценариев, все пользователи, использующие их, используют use lib
/ no lib
pragmas в самой программе. Его также следует использовать, когда каталог, который необходимо найти, должен быть динамически определен во время выполнения - например, из параметров командной строки сценария или пути сценария (см. Очень хороший пример использования в модуле FindBin ).
Если каталогами @INC
нужно манипулировать в соответствии с какой-то сложной логикой, которую невозможно или слишком громоздко реализовать с помощью комбинации use lib
/ no lib
прагм, то используйте прямое @INC
манипулирование внутри BEGIN {}
блока или внутри специальной библиотеки, предназначенной для@INC
манипуляции, которая должна использоваться вашим сценарием (s) перед использованием любых других модулей.
Примером этого является автоматическое переключение между библиотеками в каталогах prod / uat / dev, с водопадной библиотекой в prod, если она отсутствует в dev и / или UAT (последнее условие усложняет стандартное решение "use lib + FindBin". A подробные иллюстрации этого сценария в Как использовать бета - модули Perl из бета - скриптов на Perl? .
Дополнительный вариант использования для прямого манипулирования @INC
- это возможность добавлять ссылки на подпрограммы или ссылки на объекты (да, Вирджиния @INC
может содержать собственный код Perl, а не только имена каталогов, как объясняется в разделе Когда вызывается ссылка на подпрограмму в @INC? ).