Ми розглянемо, як побудовано вміст цього масиву і чи можемо ними маніпулювати впливати на те, де інтерпретатор 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використовується) змінної середовища вашої оболонки. Щоб побачити зміст змінних @INCafter 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
Передайте його через перший рядок (шебанг) вашого сценарію 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через viano lib .
Ви можете безпосередньо маніпулювати @INCяк звичайний масив Perl.
Примітка: Оскільки @INCвикористовується на етапі компіляції, це потрібно зробити всередині BEGIN {}блоку, який передує use MyModuleоператору.
Додайте каталоги до початку через unshift @INC, $dir.
Додайте каталоги до кінця через push @INC, $dir.
Робіть все, що ви можете зробити з масивом Perl.
Примітка: каталоги зрушать на @INCв порядку , зазначеному в цій відповіді, наприклад , по замовчуванням @INCє останнім у списку, з яким передує PERL5LIB, передує -I, передують use libі прямий @INCманіпуляції, останні два змішуватися в залежності від того , замовити їх в коді Perl.
Список літератури:
Здається, не існує всеосяжної @INCпублікації типу поширених запитань про Stack Overflow, тому це питання призначене як одне.
Коли використовувати кожен підхід?
Якщо модулі в каталозі потребують використання багатьох / всіх скриптів на вашому веб-сайті, особливо під керуванням декількох користувачів, цей каталог повинен бути включений до типового @INCзбору у бінарний файл Perl.
Якщо модулі в каталозі будуть використовуватися виключно певним користувачем для всіх сценаріїв, якими користувач запускає (або якщо перекомпіляція Perl не є можливістю змінити типовий режим @INCу попередньому випадку використання), встановіть користувача PERL5LIB, як правило, під час входу в систему.
Примітка. Будь ласка, пам’ятайте про звичні підводні камені змінної середовища Unix - наприклад, у деяких випадках запуск сценаріїв як певний користувач не гарантує запуск їх із налаштованим середовищем цього користувача, наприклад через su.
Якщо модулі в каталозі потрібно використовувати лише в конкретних обставинах (наприклад, коли сценарій (и) виконуються в режимі розробки / налагодження, ви можете встановити його PERL5LIBвручну або передати -Iпараметр perl.
Якщо модулі потрібно використовувати лише для певних сценаріїв, всі користувачі, які їх використовують, використовують use lib/ no libпрагми в самій програмі. Він також повинен використовуватися, коли каталог, який потрібно шукати, повинен бути динамічно визначений під час виконання - наприклад, з параметрів командного рядка сценарію або шляху сценарію (див. Модуль FindBin для дуже гарного випадку використання).
Якщо @INCпотрібні маніпуляції з каталогами за якоюсь складною логікою або неможливо занадто непросто реалізувати за допомогою комбінації use lib/ no libpragmas, тоді використовуйте прямі @INCманіпуляції всередині BEGIN {}блоку або всередині бібліотеки спеціального призначення, призначеної для @INCманіпуляцій, яку повинен використовувати ваш сценарій (и) до використання будь-яких інших модулів.
Прикладом цього є автоматичне перемикання між бібліотеками в каталогах prod / uat / dev, з підхопленням бібліотеки водоспадів у prod, якщо в програмі відсутнє програмне забезпечення dev та / або UAT (остання умова робить стандартне рішення "використання lib + FindBin" досить складним.) Детальна ілюстрація цього сценарію наведена в розділі Як використовувати модулі бета-Perl із сценаріїв бета-версії Perl ? .
Додатковим випадком використання для прямого маніпулювання @INCє можливість додати посилання підпрограми або посилання на об'єкти (так, Вірджинія, @INCможе містити користувацький код Perl, а не лише імена каталогів, як пояснено у розділі Коли називається посилання підпрограми в @INC? ).