Perl's @INC nasıl inşa edilir? (aka Perl modüllerinin arandığı yerleri etkilemenin tüm yolları nelerdir?)


200

Perl modüllerinin nerede arandığını etkilemenin tüm yolları nelerdir? veya, Perl's @INC nasıl inşa edilir ?

Bildiğimiz gibi, Perl@INC Perl modül dosyalarını nerede arayacağınızı belirlemek için dizin adlarını içeren diziyi .

StackOverflow üzerinde kapsamlı bir "@INC" SSS tipi yazı yok gibi görünüyor, bu nedenle bu soru bir olarak tasarlanmıştır.


7
Evet, ama search.cpan.org/perldoc/… 'da mükemmel bir tane var mı?
mafya

3
@mobrule: Bunun kapsamlı bir yere yakın olduğunu düşünmüyorum - sadece @INCtam zamanında değil, çalışma zamanında nasıl ekleneceğini anlatıyor .
Cascabel

2
@mobrule - @Jefromi doğru tahmin - HERHANGİ ana sorunu ve şimdiye kadar perl ikili en derlenmiş-varsayılan @ INC hakkında kapsamlı bilgi eksikliği olduğunu bulduk tüm referansları
DVK

3
Bazıları bana bir yama göndererek bu cevabı kapsamlı yapabilir. Bu kolay çünkü perlfaq Github'da. :)
brian d foy

1
Peki, "perl binary derlenmiş varsayılan @INC hakkında kapsamlı bilgi" onu derleyen kişinin kurduğu kişi olmasıdır. Oraya giren çeşitli yollar hakkında soru soruyorsanız, cevapladığınız sorudan farklı bir sorunuz olduğunu düşünüyorum.
brian d foy

Yanıtlar:


254

Bu dizinin içeriğinin nasıl oluşturulduğuna bakacağız ve Perl yorumlayıcısının modül dosyalarını nerede bulacağını etkileyecek şekilde manipüle edilebileceğine bakacağız.

  1. Varsayılan @INC

    Perl yorumlayıcısı belirli bir @INCvarsayılan değerle derlenir . Bu değeri bulmak için, env -i perl -Vkomutu çalıştırın ( çevresel değişkeni env -iyoksayar PERL5LIB- bakınız # 2) ve çıktıda şöyle bir şey göreceksiniz:

    $ 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
     .

Not .sonunda; bu geçerli dizindir (komut dosyasının diziniyle aynı olması gerekmez). Perl 5.26+ ve Perl ile çalıştığında -T(renk kontrolleri etkin) eksiktir .

Perl ikili derlemesini yapılandırırken varsayılan yolu değiştirmek için yapılandırma seçeneğini ayarlayın otherlibdirs:

Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3

  1. Çevresel değişken PERL5LIB(veya PERLLIB)

    Perl , kabuğunuzun ortam değişkeninde ( tanımlanmamışsa, kullanılıyorsa) @INCbulunan dizinlerin (iki nokta üst üste ayrılmış) bir listesini önceden bekler . İçeriğini görmek için sonra ve , çalışma ortam değişkenleri etkisini gösterdiğindePERL5LIBPERLLIB@INCPERL5LIBPERLLIBperl -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
     .
  2. -I komut satırı seçeneği

    Perl ön ekler @INC , -Ikomut satırı seçeneğinin değeri olarak iletilen dizinlerin bir listesiyle (iki nokta üst üste ayrılmış) . Bu, Perl seçenekleriyle her zamanki gibi üç şekilde yapılabilir:

    • Komut satırına iletin:

      perl -I /my/moduledir your_script.pl
    • Perl betiğinizin ilk satırından (shebang) geçin:

      #!/usr/local/bin/perl -w -I /my/moduledir
    • PERL5OPT(Veya PERLOPT) ortam değişkeninin bir parçası olarak iletin (bkz. Bölüm 19.02, Perl Programlama )

  3. Pragma yoluyla libgeçirin

    Perl ön ekler @INC , üzerinden geçirilen dizinlerin bir listesi ileuse lib .

    Bir programda:

    use lib ("/dir1", "/dir2");

    Komut satırında:

    perl -Mlib=/dir1,/dir2

    Ayrıca edebilirsiniz gelen dizinleri kaldırmak @INCyoluylano lib .

  4. Doğrudan @INCdüzenli bir Perl dizisi olarak manipüle edebilirsiniz .

    Not: @INCDerleme aşamasında kullanıldığından, bu ifadeden BEGIN {}önce gelen bir blok içinde yapılmalıdır use MyModule.

    • Başlangıç ​​noktasına dizinleri ekleyin unshift @INC, $dir.

    • Yoluyla dizinleri sonuna ekleyin push @INC, $dir.

    • Perl dizisi ile yapabileceğiniz her şeyi yapın.

Not: dizinleri vardır elenmemiş üzerine @INCbu cevap listelenen sırada, mesela varsayılan @INCöncesinde listede, son olup PERL5LIBöncesinde, -I, öncesinde use libve doğrudan@INC onlar Perl kodu vardır sipariş hangisi içinde manipülasyon, son iki karışık.

Referanslar:

Kapsamlı görünmüyor @INCStack Overflow'da SSS tipi yazı , bu nedenle bu soru bir soru olarak tasarlanmıştır.

Her yaklaşım ne zaman kullanılır?

  • Bir dizindeki modüllerin, özellikle birden çok kullanıcı tarafından çalıştırılan sitenizdeki pek çok / tüm komut dosyası tarafından kullanılması gerekiyorsa, bu dizin varsayılana dahil edilmelidir @INC Perl ikili dosyasında derlenen .

  • Dizindeki modüller yalnızca kullanıcının çalıştırdığı tüm komut dosyaları için belirli bir kullanıcı tarafından kullanılacaksa (veya Perl'i yeniden derlemek varsayılanı değiştirmek için bir seçenek değilse @INC önceki kullanım durumunda ) PERL5LIB, genellikle kullanıcı oturum açma sırasında kullanıcıların 'sini ayarlayın.

    Not: Lütfen her zamanki Unix ortam değişkeni tuzaklarından haberdar olun - örneğin, belirli durumlarda komut dosyalarını çalıştırmak gibi belirli bir kullanıcı tarafından çalıştırıldığında, bu kullanıcının ortam kurulumuyla çalıştırılacağı garanti edilmez su .

  • Dizindeki modüllerin yalnızca belirli durumlarda kullanılması gerekiyorsa (örn. Komut dosyaları geliştirme / hata ayıklama modunda yürütüldüğünde, PERL5LIBmanuel olarak ayarlayabilir veya-I seçeneği perl'e .

  • Modüllerin yalnızca belirli komut dosyaları için kullanılması gerekiyorsa, bunları kullanan tüm kullanıcılar tarafından , programın kendisinde use lib/ no libpragmas kullanın . Ayrıca, aranacak dizinin çalışma sırasında dinamik olarak belirlenmesi gerektiğinde de kullanılmalıdır - örneğin komut dosyasının komut satırı parametrelerinden veya komut dosyasının yolundan ( çok güzel kullanım durumu için FindBin modülüne bakın ).

  • @INCBazı karmaşık mantığa göre manipüle edilmesi gereken dizinlerin use lib/ no libpragmas kombinasyonu ile uygulanamayacak kadar zor olması imkansızsa , @INCiçinde doğrudan manipülasyon kullanınBEGIN {} blok içinde veya özel olarak tasarlanmış özel bir kütüphane içinde@INC manipülasyon . diğer modüller kullanılmadan önce.

    Bunun bir örneği prod / uat / dev dizinlerindeki kütüphaneler arasında otomatik olarak geçiş yapmaktır, dev ve / veya UAT'den eksikse prod'da şelale kütüphanesi alımı (son koşul standart "lib + FindBin kullan" çözümünü oldukça karmaşık hale getirir. Bu senaryonun detaylı illüstrasyon olduğunu ben beta Perl komut beta Perl modülleri kullanırım nasıl? .

  • Doğrudan işlemek için ek bir kullanım durumunda @INCaltprogram referansları veya nesne referanslarını (evet, Virginia eklemek mümkün olmaktır @INCaçıklandığı gibi özel Perl kodu ve sadece dizin adları içerebilir denilen @ INC bir altprogram başvuru olduğunda? ).


1
-I ayarlayabilirsiniz PERLOPT unutmayın. Ayrıca, base.pm ve local :: lib gibi şeyler, listelediklerinizi dolaylı olarak kullanır.
brian d foy

1
@brian - use :: base, altındaki "gereksinim" nedeniyle IIRC kullanır. Local :: lib'e aşina değilim, bunun ne olduğunu anlamak için daha fazla okumaya ihtiyacım olacak
DVK

3
Ayrıca, bunu gerçekten iyi bir cevap haline getirmek için, insanlara her birini ne zaman kullanmaları gerektiğini söylemeniz gerekir. Onlara nasıl olabilecekleri konusunda 10 seçenek vermek çok yararlı değil. :)
brian d foy

PS Herkes, cevabı -I / use lib aracılığıyla ikinci bir mimariye özgü dizin içerme dahil etmek üzere düzenlemek için çekinmeyin. Kendimi daha sonra yapmayı planladım, ancak şimdilik çevrimdışı olmalıyım.
DVK

@brian - PERLOPT eklendi. Ben base.pm ve diğer "ne zaman @INC kullanılır" öğeleri bahsetmek gibi hissediyorum daha buraya gelen ve bağlı @ INC / bulma modül dosyaları SSS için daha uygundur, bu yüzden orada koymak.
DVK

18

Yukarıda listelenen konumlara ek olarak, Perl'in OS X sürümünde iki yol daha vardır:

  1. /Library/Perl/x.xx/AppendToPath dosyası. Bu dosyada listelenen yollar çalışma zamanında @INC'a eklenir.

  2. /Library/Perl/x.xx/PrependToPath dosyası. Bu dosyada listelenen yollar çalışma zamanında @INC eklenir.


6

Daha önce de söylendiği gibi @INC bir dizidir ve istediğiniz her şeyi eklemekte özgürsünüz.

CGI REST betiğim şöyle görünüyor:

#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
    push @INC, 'fully_qualified_path_to_module_wiht_our_REST.pm';
}
use Modules::Rest;
gone(@_);

Alt program gitti Rest.pm tarafından dışa aktarılıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.