Kami akan melihat bagaimana isi array ini dibangun dan dapat dimanipulasi untuk mempengaruhi di mana penerjemah Perl akan menemukan file-file modul.
Default @INC
Interpreter perl dikompilasi dengan @INCnilai default tertentu . Untuk mengetahui nilai ini, jalankan env -i perl -Vperintah ( env -iabaikan PERL5LIBvariabel lingkungan - lihat # 2) dan pada output Anda akan melihat sesuatu seperti ini:
$ 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
.
Catatan .di akhir; ini adalah direktori saat ini (yang tidak harus sama dengan direktori skrip). Itu hilang dalam Perl 5.26+, dan ketika Perl berjalan dengan -T(pemeriksaan noda diaktifkan) .
Untuk mengubah jalur default saat mengonfigurasi kompilasi biner Perl, tetapkan opsi konfigurasi otherlibdirs:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3
Variabel lingkungan PERL5LIB(atauPERLLIB )
Perl pra-pends @INCdengan daftar direktori (dipisahkan dengan titik dua) yang terkandung dalam PERL5LIB(jika tidak ditentukan, PERLLIBdigunakan) variabel lingkungan shell Anda. Untuk melihat konten variabel @INCafter PERL5LIBdan PERLLIBenvironment telah diterapkan, jalankan 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 opsi baris perintah
Perl pra-pends @INCdengan daftar direktori (dipisahkan dengan titik dua) dilewatkan sebagai nilai -Iopsi baris perintah. Ini dapat dilakukan dengan tiga cara, seperti biasa dengan opsi Perl:
Lulus di baris perintah:
perl -I /my/moduledir your_script.pl
Lulus melalui baris pertama (shebang) skrip Perl Anda:
#!/usr/local/bin/perl -w -I /my/moduledir
Lulus sebagai bagian dari PERL5OPT(atau PERLOPT) variabel lingkungan (lihat bab 19.02 di Pemrograman Perl )
Berikan itu melalui libpragma
Perl pra-pends @INCdengan daftar direktori yang dikirimkan kepadanyause lib .
Dalam sebuah program:
use lib ("/dir1", "/dir2");
Di baris perintah:
perl -Mlib=/dir1,/dir2
Anda juga dapat menghapus direktori dari @INCviano lib .
Anda bisa langsung memanipulasi @INC sebagai array Perl biasa.
Catatan: Karena @INCdigunakan selama fase kompilasi, ini harus dilakukan di dalam BEGIN {}blok, yang mendahului use MyModulepernyataan.
Tambahkan direktori ke awal via unshift @INC, $dir.
Tambahkan direktori ke bagian akhir via push @INC, $dir.
Lakukan hal lain yang dapat Anda lakukan dengan array Perl.
Catatan: Direktori tidak diubah ke @INCdalam urutan yang tercantum dalam jawaban ini, misalnya default @INCterakhir dalam daftar, didahului oleh PERL5LIB, didahului oleh -I, didahului oleh use libdan diarahkan@INC dimanipulasi , dua yang terakhir dicampur dalam urutan mana pun mereka berada dalam kode Perl.
Referensi:
Sepertinya tidak ada @INCposting tipe FAQ yang komprehensif di Stack Overflow, jadi pertanyaan ini dimaksudkan sebagai satu.
Kapan harus menggunakan setiap pendekatan?
Jika modul dalam direktori perlu digunakan oleh banyak / semua skrip di situs Anda, terutama dijalankan oleh banyak pengguna, direktori itu harus dimasukkan dalam default yang @INCdikompilasi ke biner Perl.
Jika modul dalam direktori akan digunakan secara eksklusif oleh pengguna tertentu untuk semua skrip yang dijalankan pengguna (atau jika mengkompilasi ulang Perl bukan opsi untuk mengubah default @INCdalam kasus penggunaan sebelumnya), atur pengguna PERL5LIB, biasanya selama login pengguna.
Catatan: Perlu diketahui perangkap variabel lingkungan Unix yang biasa - misalnya dalam menjalankan skrip tertentu sebagai pengguna tertentu tidak menjamin menjalankannya dengan pengaturan lingkungan pengguna itu, misalnya via su.
Jika modul dalam direktori hanya perlu digunakan dalam keadaan tertentu (misalnya ketika skrip dieksekusi dalam mode pengembangan / debug, Anda dapat mengatur PERL5LIBsecara manual, atau meneruskan -Iopsi ke perl.
Jika modul hanya perlu digunakan untuk skrip tertentu, oleh semua pengguna yang menggunakannya, gunakan use lib/ no libpragma dalam program itu sendiri. Ini juga harus digunakan ketika direktori yang akan dicari harus ditentukan secara dinamis selama runtime - misalnya dari parameter baris perintah skrip atau jalur skrip (lihat modul FindBin untuk kasus penggunaan yang sangat bagus).
Jika direktori yang @INCperlu dimanipulasi sesuai dengan beberapa logika yang rumit, tidak mungkin terlalu sulit untuk diterapkan dengan kombinasi use lib/ no libpragma, maka gunakan @INCmanipulasi langsung di dalam BEGIN {}blok atau di dalam perpustakaan tujuan khusus yang ditunjuk untuk@INC manipulasi, yang harus digunakan oleh skrip Anda (s) sebelum modul lain digunakan.
Contoh dari hal ini adalah secara otomatis beralih antar perpustakaan dalam direktori prod / uat / dev, dengan pickup perpustakaan air terjun di prod jika hilang dari dev dan / atau UAT (kondisi terakhir membuat solusi standar "gunakan lib + FindBin" cukup rumit. A ilustrasi rinci dari skenario ini adalah di Bagaimana cara menggunakan modul Perl beta dari skrip Perl beta? .
Kasus penggunaan tambahan untuk memanipulasi secara langsung @INCadalah untuk dapat menambahkan referensi subrutin atau referensi objek (ya, Virginia, @INCdapat berisi kode Perl khusus dan bukan hanya nama direktori, seperti yang dijelaskan dalam Kapan referensi subrutin dalam @INC disebut? ).