Jak powstaje @INC Perla? (aka jakie są wszystkie sposoby wpływania na to, gdzie Moduły Perla są wyszukiwane?)

Jakie są wszystkie sposoby wpływania na to, gdzie Moduły Perla są wyszukiwane? albo Jak jest skonstruowany @ INC Perla ?

Jak wiemy, Perl używa tablicy @INC zawierającej nazwy katalogów, aby określić, gdzie szukać plików modułów Perla.

Wydaje się, że nie ma wyczerpującego postu typu FAQ "@INC" na StackOverflow, więc to pytanie jest zamierzone jako jedno.

Author: Community, 2010-03-26

3 answers

Przyjrzymy się, jak zawartość tej tablicy jest konstruowana i może być manipulowana, aby wpływać na to, gdzie interpreter Perla znajdzie pliki modułów.

  1. Default @INC

    Interpreter Perla jest skompilowany z konkretną @INC wartością domyślną. Aby dowiedzieć się o tej wartości, uruchom polecenie env -i perl -V (env -i ignoruje zmienną środowiskową PERL5LIB - patrz #2), a na wyjściu zobaczysz coś takiego:

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

Uwaga . na końcu; jest to bieżący katalog (który niekoniecznie jest taki sam jak katalog skryptu). Brakuje go w Perlu 5.26+, a gdy Perl działa z -T (taint checks enabled) .

Aby zmienić domyślną ścieżkę podczas konfigurowania kompilacji binarnej Perla, ustaw opcję configuration otherlibdirs:

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

  1. Zmienna środowiskowa PERL5LIB (lub PERLLIB)

    Perl pre-pends @INC z listą katalogi (rozdzielone dwukropkami) zawarte w PERL5LIB (jeśli nie jest zdefiniowana, używane jest PERLLIB) zmiennej środowiskowej powłoki. Aby sprawdzić zawartość @INC po wprowadzeniu zmiennych środowiskowych PERL5LIB i PERLLIB, Uruchom 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
     .
    
  2. -I opcja wiersza poleceń

    Perl Pre-penduje @INC z listą katalogów (rozdzielonych dwukropkami) przekazaną jako wartość opcji linii poleceń -I. Można to zrobić na trzy sposoby, jak zwykle w Perlu opcje:

    • Podaj w wierszu poleceń:

      perl -I /my/moduledir your_script.pl
      
    • Podaj pierwszy wiersz (shebang) skryptu Perla:

      #!/usr/local/bin/perl -w -I /my/moduledir
      
    • Przekazać ją jako część zmiennej środowiskowej PERL5OPT (lub PERLOPT) (patrz rozdział 19.02 w Programowanie Perla)

  3. Podaj przez lib pragma

    Perl Pre-penduje @INC z listą katalogów przekazanych do niego przez use lib.

    W program:

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

    W wierszu poleceń:

    perl -Mlib=/dir1,/dir2
    

    Możesz również usunąć katalogi z @INC poprzez no lib.

  4. Możesz bezpośrednio manipulować @INC jako zwykłą tablicę Perla.

    Uwaga: Ponieważ @INC jest używane w fazie kompilacji, musi to być wykonane wewnątrz bloku BEGIN {}, który poprzedza instrukcję use MyModule.

    • Dodawanie katalogów do początku poprzez unshift @INC, $dir.

    • Dodaj katalogi do end via push @INC, $dir.

    • Zrób wszystko, co możesz zrobić za pomocą tablicy Perla.

Uwaga: katalogi są unshifted na @INC w kolejności podanej w tej odpowiedzi, np. default @INC jest ostatni na liście, poprzedzony PERL5LIB, poprzedzony -I, poprzedzony use lib i direct @INC manipulation, dwa ostatnie są mieszane w dowolnej kolejności w kodzie Perla.

Bibliografia:

Nie wydaje się być wyczerpujący @INC FAQ-wpisz post na Stack Overflow, więc to pytanie jest przeznaczone jako jeden.

Kiedy stosować każde podejście?

  • Jeśli Moduły w katalogu muszą być używane przez wiele / wszystkie skrypty w Twojej witrynie, szczególnie przez wielu użytkowników, katalog ten powinien być zawarty w domyślnej @INC skompilowanej do pliku binarnego Perla.

  • Jeśli Moduły w katalogu będą używane wyłącznie przez konkretnego użytkownika dla wszystkich skryptów uruchamianych przez użytkownika (lub jeśli rekompilacja Perla nie jest opcją aby zmienić domyślne @INC w poprzednim przypadku użycia), należy ustawić PERL5LIB użytkownika, zwykle podczas logowania użytkownika.

    Uwaga: Należy pamiętać o typowych pułapkach zmiennych środowiska Unix - np. w niektórych przypadkach uruchomienie skryptów jako konkretnego użytkownika nie gwarantuje ich uruchomienia z skonfigurowanym środowiskiem użytkownika, np. poprzez su.

  • Jeśli Moduły w katalogu muszą być używane tylko w określonych okolicznościach (np. gdy skrypt(y) jest wykonywany w tryb programowania/debugowania, możesz albo ustawić PERL5LIB ręcznie, albo przekazać opcję -I do Perla.

  • Jeśli moduły muszą być używane tylko dla określonych skryptów, przez wszystkich użytkowników korzystających z nich, użyj use lib/no lib pragmaty w samym programie. Powinien być również stosowany, gdy katalog do przeszukiwania musi być dynamicznie ustalany podczas wykonywania-np. z parametrów wiersza poleceń skryptu lub ścieżki skryptu (patrz moduł FindBin dla bardzo przyjemnego zastosowania case).

  • Jeśli katalogi w @INC muszą być manipulowane zgodnie z jakąś skomplikowaną logiką, albo niemożliwe do zaimplementowania przez kombinację use lib/no lib pragmas, następnie użyj bezpośredniej manipulacji @INC wewnątrz bloku BEGIN {} lub wewnątrz specjalnej biblioteki przeznaczonej do manipulacji @INC, która musi być użyta przez twój skrypt(y) przed użyciem innych modułów.

    Przykładem tego jest automatyczne przełączanie się między bibliotekami w prod / uat/dev katalogi, z waterfall library pickup w prod, jeśli brakuje go w dev i/lub UAT (ostatni warunek sprawia, że standardowe rozwiązanie "use lib + FindBin" jest dość skomplikowane. Szczegółowa ilustracja tego scenariusza znajduje się w jak używać modułów beta Perla ze skryptów beta Perla?.

  • Dodatkowym przypadkiem użycia do bezpośredniego manipulowania @INC jest możliwość dodawania referencji podprogramów lub odniesień do obiektów (tak, Virginia, {[6] } może zawierać Niestandardowy Perl kod, a nie tylko nazwy katalogów, jak wyjaśniono w kiedy wywołana jest Referencja podprogramu w @INC?).

 254
Author: DVK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-12 12:30:15

Oprócz lokalizacji wymienionych powyżej, wersja OS X Perla ma również dwa inne sposoby:

  1. Plik/Library/Perl/x.xx / AppendToPath. Ścieżki wymienione w tym pliku są dołączane do @INC w czasie wykonywania.

  2. Plik/Library/Perl/x.xx / PrependToPath. Ścieżki wymienione w tym pliku są poprzedzone znakiem @ INC w czasie wykonywania.

 18
Author: dgatwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-11 19:24:16

Jak już zostało powiedziane @INC jest tablicą i możesz dodać cokolwiek chcesz.

Mój skrypt CGI REST wygląda następująco:

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

Podprogram gone jest eksportowany przez Rest.pm.

 7
Author: Kacper Perschke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-04 22:16:19