r4 - 18 Sep 2006 - NicholasAmorim
- NOME
- SINOPSE
- DESCRIÇÂO
- Subroutine Stubs
- Usando a subrotina AUTOLOAD de AutoLoader
- Reescrevendo a rotina AUTOLOAD de AutoLoader's
- Léxicos no pacote
- Não usando AutoLoader
- AutoLoader vs. SelfLoader
- PROBLEMAS
- VEJA TAMBÉM
- TRADUÇÃO
NOME
AutoLoader - carrega subrotinas sob demanda (apenas quando são executadas)SINOPSE
package Foo;
use AutoLoader 'AUTOLOAD'; # importa a subrotina padrão AUTOLOAD
package Bar;
use AutoLoader; # Não importa AUTOLAOD, definiremos o nosso
sub AUTOLOAD {
...
$AutoLoader::AUTOLOAD = "...";
goto &AutoLoader::AUTOLOAD;
}
DESCRIÇÂO
O módulo AutoLoader funciona em conjunto com o módulo AutoSplit? e a marca__END__ para atrasar o carregamento de algumas subrotinas até que eles
sejam usados, ao invés de carregá-los todos de uma vez.
Para usar o AutoLoader, o autor de um módulo precisa colocar as definições
de subrotinas a serem autocarregadas (``autoloaded'') depois da marca __END__.
(Veja the perldata manpage.) O módulo AutoSplit? pode então ser executado manualmente
para extrair as definições para arquivos individuais auto/funcname.al.
AutoLoader implementa uma subrotina AUTOLOAD. Quando uma subrotina indefinida
é chamada em um módulo cliente de AutoLoader, a subrotina AUTOLOAD tenta localizar
a subrotina em um arquivo com nome relacionado com a localização do arquivo a partir
do qual o módulo cliente foi lido.
Apenas como exemplo, se POSIX.pm estiver localizado em
/usr/local/lib/perl5/POSIX.pm, AutoLoader vai procurar pelas subrotinas POSIX
em /usr/local/lib/perl5/auto/POSIX/*.al, onde o arquivo .al tem o mesmo nome
da subrotina, sem o pacote. Se tal arquivo existir, AUTOLOAD irá ler e avaliar (eval)
seu conteúdo, definindo assim, a subrotina necessária. AUTOLOAD salta então
(goto) para a subrotina recém-definida.
Uma vez que este processo tenha sido completado para uma dada função, ela está
definida, de maneira que as futuras chamadas para a subrotina não precisarão passar
pelo mecanismo de AUTOLOAD.
Subroutine Stubs
Para fazer a busca nos métodos do objeto e/ou checagem de protótipos funcionarem corretamente mesmo quando os métodos não foram ainda definidos é necessário declarar previamente cada subrotina (como emsub NAME;). Veja SYNOPSIS in the perlsub manpage.
Tal declaração prévia cria uma 'topografia da subrotina', que declaram a função sem código.
Os módulos AutoSplit? e AutoLoad automatizam a criação de declarações prontas.
O módulo AutoSplit? cria um arquivo de 'índice' contendo todas as declarações prontas
de todas as subrotinas do AutoSplit? . Quando o módulo AutoLoader é usado (utilizando use),
essas declarações são carregadas no pacote que o chamou.
Por causa desse mecanismo é importante que AutoLoad seja sempre
usado (usando use) e não requirido (usando require).
Usando a subrotina AUTOLOAD de AutoLoader
Para poder usar a subrotina AUTOLOAD de AutoLoader você deve explicitamente importá-la.
use AutoLoader 'AUTOLOAD';
Reescrevendo a rotina AUTOLOAD de AutoLoader's
Alguns módulos, principalmente extensões, provêm sua própria subrotina AUTOLOAD. Eles tipicamente precisam checar por alguns casos especiais (como constantes) e então voltar para o AUTOLOAD de AutoLoader para o resto. Tais módulos não devem importar a subrotina AUTOLOAD de AUtoLoad Em vez disso, eles devem defininer sua própria subrotina AUTOLOAD com essas linhas:
use AutoLoader;
use Carp;
sub AUTOLOAD {
my $sub = $AUTOLOAD;
(my $constname = $sub) =~ s/.*:://;
my $val = constant($constname, @_ ? $_[0] : 0);
if ($! != 0) {
if ($! =~ /Invalid/ || $!{EINVAL}) {
$AutoLoader::AUTOLOAD = $sub;
goto &AutoLoader::AUTOLOAD;
}
else {
croak "Your vendor has not defined constant $constname";
}
}
*$sub = sub { $val }; # same as: eval "sub $sub { $val }";
goto &$sub;
}
Se qualquer AUTOLOAD próprio de uma subrotina de um módulo não precisar
voltar para o AUTOLOAD do AutoLoader (porquê não tem nenhuma subrotina AutoSplit? ),
então o módulo NÃO deve usar AutoLoader.
Léxicos no pacote
Léxicos do pacote declarados commy no bloco principal do pacote
usando AutoLoad não será visível para as subrotinas automaticamente carregas, dado o fato
que os escopos dados termina no marcador __END__. Um módulo usando
tais variávels como globais não vai funcionar corretamente com o AutoLoader.
O pragma vars (veja vars in the perlmod manpage) pode ser usado em tais
situações como uma alternativa para qualificar explicitamente todas as variáveis
globais no namespace do pacote. Variáveis pré-declaradas com este pragma
estarão visíveis para qualquer subrotina automaticamente carregada (mas não estarão
invisíveis fora do pacote, infelizmente).
Não usando AutoLoader
Você pode parar de usar o AutoLoad? simplesmente utilizando:
no AutoLoader;
AutoLoader vs. SelfLoader
O AutoLoader é similar em objetivo ao SelfLoader: ambos atrasam o carregamento de carregar subrotinas. SelfLoad usa o marcador__DATA__ do que __END__.
Enquanto isso evita o uso da hierarquia dos arquivos em disco e o open/close
de cada rotina é carregado, SelfLoader sofre de um desvantagem no tempo
de inicialização no parsing feito de uma vez só das linhas após __DATA__, no qual suas
rotinas estão no cache. SelfLoader pode também lidar com múltiplos pacotes em um arquivo.
AutoLoad somente lê código quando é requisitado, e em muitos casos
deve ser rápido, mas requer que um mecanismo como AutoSplit seja
usado para criar arquivos individuais. the ExtUtilsMakeMaker? manpage irá invocar
AutoSplit automaticamente se AutoLoad é usado em um código-fonte de um módulo.
PROBLEMAS
AutoLoaders antes de Perl 5.002 tinham uma interface ligeiramente diferente. Quaisquer módulos antigos que usem AutoLoader devem ser modificados para o novo estilo de chamada. Isso tipicamente significa apenas mudar um ``require'' para ``use'', adicionar a importação de'AUTOLOAD' explícita se necessário,
e remover AutoLoader de @ISA.
Em sistemas com restrições no comprimento de nomes de arquivos, o arquivo
correspondente a uma subrotina pode ter um nome mais curto do que a subrotina
em si. Isso pode levar a nomes conflitantes. O pacote AutoSplit? avisará sobre
estes possíveis conflitos quando for usado para dividir um módulo.
AutoLoader pode não conseguir encontrar os arquivos de autosplit (ou mesmo
encontrar arquivos errados) em casos em que @INC contenha caminhos
relativos e o programa execute um chdir.
