Veremos como o conteúdo dessa matriz é construído e pode ser manipulado para afetar onde o interpretador Perl encontrará os arquivos do módulo.
Padrão @INC
O interpretador Perl é compilado com um @INCvalor padrão específico . Para descobrir esse valor, execute o env -i perl -Vcomando ( env -iignora a PERL5LIBvariável ambiental - consulte o item 2) e na saída você verá algo como isto:
$ 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
.
Nota .no final; esse é o diretório atual (que não é necessariamente o mesmo que o diretório do script). Está faltando no Perl 5.26+ e quando o Perl é executado com -T(verificações de contaminação ativadas) .
Para alterar o caminho padrão ao configurar a compilação binária Perl, defina a opção de configuração otherlibdirs:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3
Variável ambiental PERL5LIB(ou PERLLIB)
O Perl se antecipa a @INCuma lista de diretórios (separados por dois pontos) contidos na PERL5LIB(se não definida, PERLLIBé usada) variável de ambiente do seu shell. Para ver o conteúdo das variáveis @INCafter PERL5LIBe PERLLIBenvironment entraram em vigor, execute 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 opção de linha de comando
O Perl se antecipa a @INCuma lista de diretórios (separados por dois pontos) passados como valor da -Iopção da linha de comando. Isso pode ser feito de três maneiras, como de costume nas opções Perl:
Passe na linha de comando:
perl -I /my/moduledir your_script.pl
Passe-o pela primeira linha (shebang) do seu script Perl:
#!/usr/local/bin/perl -w -I /my/moduledir
Passe-o como parte da PERL5OPT(ou PERLOPT) variável de ambiente (consulte o capítulo 19.02 em Program Perl )
Passe pelo libpragma
O Perl se antecipa a @INCuma lista de diretórios transmitidos a ele via use lib.
Em um programa:
use lib ("/dir1", "/dir2");
Na linha de comando:
perl -Mlib=/dir1,/dir2
Você também pode remover os diretórios de @INCviano lib .
Você pode manipular diretamente @INCcomo uma matriz Perl regular.
Nota: Como @INCé usado durante a fase de compilação, isso deve ser feito dentro de um BEGIN {}bloco, que precede a use MyModuleinstrução.
Adicione diretórios ao início via unshift @INC, $dir.
Adicione diretórios ao final via push @INC, $dir.
Faça qualquer outra coisa que você possa fazer com uma matriz Perl.
Nota: Os diretórios são unshifted para @INCna ordem listada nesta resposta, por exemplo padrão @INCé o último na lista, precedido por PERL5LIB, precedido por -I, precedido por use libe direta @INCmanipulação, os dois últimos misturados em qualquer ordem em que estão no código Perl.
Referências:
Não parece haver uma @INCpostagem abrangente do tipo FAQ sobre Stack Overflow, portanto, essa pergunta deve ser uma delas.
Quando usar cada abordagem?
Se os módulos em um diretório precisarem ser usados por muitos / todos os scripts em seu site, especialmente executados por vários usuários, esse diretório deverá ser incluído no padrão @INCcompilado no binário Perl.
Se os módulos no diretório forem usados exclusivamente por um usuário específico para todos os scripts executados pelo usuário (ou se a recompilação do Perl não for uma opção para alterar o padrão @INCno caso de uso anterior), defina os usuários PERL5LIB, geralmente durante o login do usuário.
Nota: Esteja ciente das armadilhas comuns para variáveis de ambiente Unix - por exemplo, em certos casos, a execução dos scripts como um usuário específico não garante a execução com o ambiente do usuário configurado, por exemplo, via su.
Se os módulos no diretório precisarem ser usados apenas em circunstâncias específicas (por exemplo, quando os scripts forem executados no modo de desenvolvimento / depuração, você poderá configurar PERL5LIBmanualmente ou passar a -Iopção para perl.
Se os módulos precisarem ser usados apenas para scripts específicos, por todos os usuários, use use lib/ no libpragmas no próprio programa. Também deve ser usado quando o diretório a ser pesquisado precisar ser determinado dinamicamente durante o tempo de execução - por exemplo, a partir dos parâmetros da linha de comando ou do caminho do script (consulte o módulo FindBin para obter um ótimo caso de uso).
Se os diretórios @INCprecisarem ser manipulados de acordo com alguma lógica complicada, impossível de ser implementada com a combinação de use lib/ no libpragmas, use @INCmanipulação direta dentro do BEGIN {}bloco ou dentro de uma biblioteca de finalidade especial designada para @INCmanipulação, que deve ser usada pelo seu script antes de qualquer outro módulo ser usado.
Um exemplo disso é alternar automaticamente entre bibliotecas nos diretórios prod / uat / dev, com a retirada da biblioteca em cascata no prod se ela estiver ausente do dev e / ou UAT (a última condição torna a solução padrão "use lib + FindBin" bastante complicada. ilustração detalhada desse cenário está em Como faço para usar módulos beta Perl a partir de scripts beta Perl? .
Um caso de uso adicional para manipulação direta @INCé poder adicionar referências de sub-rotina ou referências a objetos (sim, Virginia, @INCpode conter código Perl personalizado e não apenas nomes de diretório, conforme explicado em Quando é chamada uma referência de sub-rotina no @INC? ).