Como o @INC do Perl é construído?(também conhecido como Quais são todas as maneiras de afetar onde os módulos Perl são pesquisados?)

StackOverflow https://stackoverflow.com/questions/2526804

  •  22-09-2019
  •  | 
  •  

Pergunta

Quais são todas as maneiras de afetar onde os módulos Perl são pesquisados?ou, Como o @INC do Perl é construído?

Como sabemos, Perl usa @INC array contendo nomes de diretório para determinar onde procurar por arquivos de módulo Perl.

Não parece haver uma postagem abrangente do tipo FAQ "@INC" no StackOverflow, portanto, esta pergunta pretende ser uma só.

Foi útil?

Solução

Veremos como o conteúdo deste array é construído e pode ser manipulado para afetar onde o interpretador Perl encontrará os arquivos do módulo.

  1. Padrão @INC

    O intérprete Perl é compilado com um específico @INC valor padrão.Para descobrir esse valor, execute env -i perl -V comando (env -i ignora o PERL5LIB variável ambiental - veja #2) e na saída você verá algo assim:

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

Observação . no final;este é o diretório atual (que não é necessariamente igual ao diretório do script).Está faltando no Perl 5.26+, e quando o Perl é executado com -T (verificações de contaminação habilitadas).

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

  1. Variável ambiental PERL5LIB (ou PERLLIB)

    Perl pré-pendente @INC com uma lista de diretórios (separados por dois pontos) contidos em PERL5LIB (se não estiver definido, PERLLIB é usada) variável de ambiente do seu shell.Para ver o conteúdo de @INC depois PERL5LIB e PERLLIB variáveis ​​de ambiente 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
     .
    
  2. -I opção de linha de comando

    Perl pré-pendente @INC com uma lista de diretórios (separados por dois pontos) passada como valor do -I opção de linha de comando.Isto pode ser feito de três maneiras, como de costume com 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 como parte de PERL5OPT (ou PERLOPT) variável de ambiente (consulte o capítulo 19.02 em Programação Perl)

  3. Passe-o através do lib pragma

    Perl pré-pendente @INC com uma lista de diretórios passados ​​para ele via use lib.

    Em um programa:

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

    Na linha de comando:

    perl -Mlib=/dir1,/dir2
    

    Você também pode remova os diretórios de @INC através da no lib.

  4. Você pode manipular diretamente @INC como uma matriz Perl regular.

    Observação:Desde @INC é usado durante a fase de compilação, isso deve ser feito dentro de um BEGIN {} bloco, que antecede o use MyModule declaraçã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 um array Perl.

Observação:Os diretórios são inalterado para @INC na ordem listada nesta resposta, por ex.padrão @INC é o último da lista, precedido por PERL5LIB, precedido por -I, precedido por use lib e direto @INC manipulação, os dois últimos misturados em qualquer ordem em que estejam no código Perl.

Referências:

Não parece haver uma abordagem abrangente @INC Postagem do tipo FAQ no Stack Overflow, portanto, esta pergunta pretende ser uma só.

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 que o usuário executa (ou se recompilar o Perl não for uma opção para alterar o padrão @INC no caso de uso anterior), defina os usuários PERL5LIB, geralmente durante o login do usuário.

    Observação:Por favor, esteja ciente das armadilhas usuais das variáveis ​​de ambiente Unix - por exemplo.em certos casos, a execução dos scripts como um usuário específico não garante sua execução com o ambiente desse usuário configurado, por exemplo.através da su.

  • Se os módulos no diretório precisarem ser usados ​​apenas em circunstâncias específicas (por exemplo,quando o(s) script(s) são executados no modo de desenvolvimento/depuração, você pode definir PERL5LIB manualmente ou passe o -I opção para perl.

  • Se os módulos precisarem ser usados ​​apenas para scripts específicos, por todos usuários que os utilizam, use use lib/no lib pragmas no próprio programa.Também deve ser usado quando o diretório a ser pesquisado precisa ser determinado dinamicamente durante o tempo de execução - por exemplo.dos parâmetros de linha de comando do script ou do caminho do script (consulte o EncontrarBin módulo para um caso de uso muito bom).

  • Se os diretórios em @INC precisam ser manipulados de acordo com alguma lógica complicada, impossível ou muito difícil de implementar pela combinação de use lib/no lib pragmas, então use direto @INC manipulação dentro BEGIN {} bloco ou dentro de uma biblioteca para fins especiais designada para @INC manipulação, que deve ser usada pelo(s) seu(s) script(s) antes de qualquer outro módulo ser usado.

    Um exemplo disso é alternar automaticamente entre bibliotecas nos diretórios prod/uat/dev, com coleta de biblioteca em cascata no prod se estiver faltando em dev e/ou UAT (a última condição torna a solução padrão "use lib + FindBin" bastante complicada.Uma ilustração detalhada deste cenário está em Como faço para usar módulos beta Perl de scripts beta Perl?.

  • Um caso de uso adicional para manipulação direta @INC é poder adicionar referências de sub-rotinas ou referências de 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 em @INC?).

Outras dicas

Além dos locais listados acima, a versão OS X do Perl também tem mais duas maneiras:

  1. O arquivo /library/perl/x.xx/appendtopath. Os caminhos listados neste arquivo são anexados ao @inc em tempo de execução.

  2. O arquivo /library/perl/x.xx/prependtopath. Os caminhos listados neste arquivo são antecipados para @inc em tempo de execução.

Como já foi dito, o @inc é uma matriz e você está livre para adicionar o que quiser.

Meu script de repouso CGI se parece:

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

A sub -rotina foi exportada por Rest.Pm.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top