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.
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.
-
Default
@INC
Interpreter Perla jest skompilowany z konkretną
@INC
wartością domyślną. Aby dowiedzieć się o tej wartości, uruchom polecenieenv -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
-
Zmienna środowiskowa
PERL5LIB
(lubPERLLIB
)Perl pre-pends
@INC
z listą katalogi (rozdzielone dwukropkami) zawarte wPERL5LIB
(jeśli nie jest zdefiniowana, używane jestPERLLIB
) zmiennej środowiskowej powłoki. Aby sprawdzić zawartość@INC
po wprowadzeniu zmiennych środowiskowychPERL5LIB
iPERLLIB
, Uruchomperl -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
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
(lubPERLOPT
) (patrz rozdział 19.02 w Programowanie Perla)
-
-
Podaj przez
lib
pragmaPerl Pre-penduje
@INC
z listą katalogów przekazanych do niego przezuse lib
.W program:
use lib ("/dir1", "/dir2");
W wierszu poleceń:
perl -Mlib=/dir1,/dir2
Możesz również usunąć katalogi z
@INC
poprzezno lib
. -
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 blokuBEGIN {}
, 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:
- perldoc perlmod
- perldoc lib
- Perl Module Mechanics-świetny przewodnik zawierający praktyczne HOW-TOs
- jak "używać" modułu Perla w katalogu spoza
@INC
? - Programowanie Perl - Rozdział 31 część 13, ch 7.2.41
- skąd program Perla wie, gdzie znaleźć plik zawierający moduł Perla, którego używa?
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 blokuBEGIN {}
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?).
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:
Plik/Library/Perl/x.xx / AppendToPath. Ścieżki wymienione w tym pliku są dołączane do @INC w czasie wykonywania.
Plik/Library/Perl/x.xx / PrependToPath. Ścieżki wymienione w tym pliku są poprzedzone znakiem @ INC w czasie wykonywania.
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.
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