Quais são todas as maneiras de afetar onde os módulos Perl são pesquisados? ou Como é construído o @INC do Perl ?
Como sabemos, o Perl usa uma @INC
matriz que contém nomes de diretório para determinar onde procurar arquivos de módulo Perl .
Não parece haver uma postagem abrangente do tipo "@INC" no StackOverflow, portanto, essa pergunta deve ser uma delas.
perl
perl-module
DVK
fonte
fonte
@INC
tempo de execução, não a construção completa.Respostas:
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
@INC
valor padrão específico . Para descobrir esse valor, execute oenv -i perl -V
comando (env -i
ignora aPERL5LIB
variável ambiental - consulte o item 2) e na saída você verá algo como isto: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
:Variável ambiental
PERL5LIB
(ouPERLLIB
)O Perl se antecipa a
@INC
uma lista de diretórios (separados por dois pontos) contidos naPERL5LIB
(se não definida,PERLLIB
é usada) variável de ambiente do seu shell. Para ver o conteúdo das variáveis@INC
afterPERL5LIB
ePERLLIB
environment entraram em vigor, executeperl -V
.-I
opção de linha de comandoO Perl se antecipa a
@INC
uma lista de diretórios (separados por dois pontos) passados como valor da-I
opçã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:
Passe-o pela primeira linha (shebang) do seu script Perl:
Passe-o como parte da
PERL5OPT
(ouPERLOPT
) variável de ambiente (consulte o capítulo 19.02 em Program Perl )Passe pelo
lib
pragmaO Perl se antecipa a
@INC
uma lista de diretórios transmitidos a ele viause lib
.Em um programa:
Na linha de comando:
Você também pode remover os diretórios de
@INC
viano lib
.Você pode manipular diretamente
@INC
como uma matriz Perl regular.Nota: Como
@INC
é usado durante a fase de compilação, isso deve ser feito dentro de umBEGIN {}
bloco, que precede ause MyModule
instruçã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
@INC
na ordem listada nesta resposta, por exemplo padrão@INC
é o último na lista, precedido porPERL5LIB
, precedido por-I
, precedido poruse lib
e direta@INC
manipulação, os dois últimos misturados em qualquer ordem em que estão no código Perl.Referências:
@INC
?Não parece haver uma
@INC
postagem 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
@INC
compilado 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
@INC
no caso de uso anterior), defina os usuáriosPERL5LIB
, 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
PERL5LIB
manualmente ou passar a-I
opção para perl.Se os módulos precisarem ser usados apenas para scripts específicos, por todos os usuários, use
use lib
/no lib
pragmas 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
@INC
precisarem ser manipulados de acordo com alguma lógica complicada, impossível de ser implementada com a combinação deuse lib
/no lib
pragmas, use@INC
manipulação direta dentro doBEGIN {}
bloco ou dentro de uma biblioteca de finalidade especial designada para@INC
manipulaçã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,@INC
pode 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? ).fonte
Além dos locais listados acima, a versão do Perl para OS X também tem mais duas maneiras:
O arquivo /Library/Perl/x.xx/AppendToPath. Os caminhos listados neste arquivo são anexados ao @INC em tempo de execução.
O arquivo /Library/Perl/x.xx/PrependToPath. Os caminhos listados neste arquivo são anexados ao @INC no tempo de execução.
fonte
Como já foi dito, o @INC é uma matriz e você pode adicionar o que quiser.
Meu script CGI REST se parece com:
A sub-rotina eliminada é exportada pelo Rest.pm.
fonte