Ми розглянемо, як побудовано вміст цього масиву і чи можемо ними маніпулювати впливати на те, де інтерпретатор 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
after 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 lib
pragmas, тоді використовуйте прямі @INC
маніпуляції всередині BEGIN {}
блоку або всередині бібліотеки спеціального призначення, призначеної для @INC
маніпуляцій, яку повинен використовувати ваш сценарій (и) до використання будь-яких інших модулів.
Прикладом цього є автоматичне перемикання між бібліотеками в каталогах prod / uat / dev, з підхопленням бібліотеки водоспадів у prod, якщо в програмі відсутнє програмне забезпечення dev та / або UAT (остання умова робить стандартне рішення "використання lib + FindBin" досить складним.) Детальна ілюстрація цього сценарію наведена в розділі Як використовувати модулі бета-Perl із сценаріїв бета-версії Perl ? .
Додатковим випадком використання для прямого маніпулювання @INC
є можливість додати посилання підпрограми або посилання на об'єкти (так, Вірджинія, @INC
може містити користувацький код Perl, а не лише імена каталогів, як пояснено у розділі Коли називається посилання підпрограми в @INC? ).