Como alterar a @INC para encontrar módulos Perl em locais não padrão?

@INC use PERLLIB PERL5LIB lib -I

Ao usar módulos que não estão instalados nos diretórios padrão do Perl, precisamos alterar a variável @INC para que o Perl possa encontra-los. Existem alguns meios de fazer isso, resolvendo diferentes casos de uso.

Vejamos primeiramente esses casos de uso:

Carregando o seu módulo Perl privado

Você tem um script e está começando a mover algumas partes do seu código para um novo módulo chamado My::Module. Você gravou o módulo em /home/foobar/code/My/Module.pm.

Seu script Perl agora começa assim:

use strict;
use warnings;

use My::Module;

Quando você executa o script você recebe uma mensagem de erro amigável como esta:

Can't locate My/Module.pm in @INC (@INC contains:
   /home/foobar/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
   /home/foobar/perl5/lib/perl5
   /etc/perl
   /usr/local/lib/perl/5.12.4
   /usr/local/share/perl/5.12.4
   /usr/lib/perl5 /usr/share/perl5
   /usr/lib/perl/5.12
   /usr/share/perl/5.12
   /usr/local/lib/site_perl
   .).
   BEGIN failed--compilation aborted.

O Perl não consegue encontrar o seu módulo.

Atualizando um módulo Perl

Você está pensando em atualizar um módulo proveniente do CPAN em um sistema qualquer. Você não quer instalar este módulo no local padrão ainda. Antes você gostaria de coloca-lo em um diretório privado, testa-lo, e instalar no sistema somente quando estiver certo de que o módulo funciona bem.

Neste caso também você "instala" o módulo em um diretório privado, por exemplo, em /home/foobar/code e de alguma forma você pretende convencer o Perl a encontrar aquela versão do módulo, e não a que está instalada no sistema.

O comando use

Quando o Perl encontra use My::Module; ele percorre os elementos do vetor @INC que contém nomes de diretórios. Em cada diretório ele verifica se existe um subdiretório chamado "My" e se dentro deste subdiretório existe um arquivo chamado "Module.pm".

O primeiro arquivo encontrado pelo Perl será carregado na memória.

Se ele não encontrar o arquivo, você recebe as mensagens de erro acima.

@INC é definida quando o Perl é compilado e ela é embutida no código binário. Você não pode mudar isso a não ser que você recompile o Perl. Não é algo que faríamos diariamente.

Por sorte o vetor @INC pode ser modificado de diversas maneiras ao executarmos um script. Vamos ver essas soluções e discutir quando cada uma delas é mais apropriada.

PERLLIB e PERL5LIB

Você pode definir a variável de ambiente PERL5LIB (ainda que PERLLIB funcione do mesmo modo, eu recomendaria usar PERL5LIB ao invés da PERLLIB por ela deixar claro que é com relação ao Perl 5) da mesma forma que você define a variável de ambiente PATH. Todo diretório listado nessa variável será adicionado ao início da @INC.

No Linux/Unix ao usar o Bash, você pode escrever

export PERL5LIB=/home/foobar/code

Você pode adicionar este comando no arquivo ~/.bashrc para disponibiliza-la sempre que fizer login.

No Windows você pode fazer o mesmo na janela do programa cmd digitando

set PERL5LIB = c:\path\to\dir

Para uma solução mais perene siga estes passos:

Clique com o botão direito em Meu Computador e clique em Propriedades.

Na janela Propriedades do Sistema, clique na aba Avançado.

Na seção Avançada, clique no botão Variáveis de Ambiente.

Na janela Variáveis de Ambiente, na seção "Variáveis do usuário para Foo Bar" clique em Nova e digite o seguinte:

Nome da Variável: PERL5LIB

Valor da Variávle: c:\path\to\dir

Então clique OK 3 vezes. As janelas que você abrir depois disso vão conhecer esta variável. Digite isso na janela de comando, para ver o valor recentemente definido:

echo %PERL5LIB%

Isso irá adicionar o diretório privado /home/foobar/code (ou c:\path\to\dir) para o início da @INC para todo script que for executado no mesmo ambiente.

No modo sujo, que será explicado em um artigo separado, as variáveis de ambiente PERLLIB e PERL5LIB são ignoradas.

use lib

Adicionar uma instrução use lib; ao script vai adicionar o diretório à @INC para aquele script específico. Independentemente de quem e em qual ambiente for executado.

Você precisa apenas se certificar que a instrução use lib foi utilizada antes de tentar carregar o módulo:

use lib '/home/foobar/code';
use My::Module;

Uma nota aqui. Vi muitas empresas onde instruções use lib foram adicionadas a módulos para que os mesmos carreguem suas dependências. Não considero isso uma boa prática. Acho que o lugar certo de modificar @INC é o script principal ou até melhor, fora do script como nas duas outras soluções.

-I na linha de comando

(Isto é um i maiúsculo)

A última solução é a mais temporária. Adicionar um parâmetro -I /home/foobar/code ao Perl ao executar o script.

perl -I /home/foobar/code script.pl

Isso vai adicionar /home/foobar/code ao início da @INC para esta execução específica do script.

Então qual delas usar?

Se você deseja somente testar a nova versão de um módulo, eu recomendaria o parâmetro da linha de comando: perl -I /path/to/lib.

Se você está instalando um conjunto de módulos em um diretório privado então eu provavelmente usaria PERL5LIB embora também veremos que o local::lib faz isso por você.

use lib é usado em dois casos:

  1. Quando você tem um local fixo, porém num ambiente não padronizado na empresa, onde se põe os módulos em um local padronizado comum.
  2. Quando você está desenvolvendo uma aplicação e você gostaria de ter certeza que o script sempre carrega os módulos de seus caminhos relativos. Vamos discutir isto em outro artigo.

Otras páginas

Perl tutorial

Author

Gabor Szabo (szabgab) Gabor Szabo