Perl Brasil

Pesquisar

Documentação

Artigos

Planeta

Eventos

Comunidade

r4 - 18 Sep 2006 - NicholasAmorim


NOME

AutoLoader - carrega subrotinas sob demanda (apenas quando são executadas)

voltar para o topo


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;
    }

voltar para o topo


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 em sub 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 com my 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.

voltar para o topo


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.

voltar para o topo


VEJA TAMBÉM

the SelfLoader? manpage - um autoloader que não usa arquivos externos

voltar para o topo


TRADUÇÃO

NicholasAmorim? <nicholasamorim@gmail.com> Nelson Ferraz <nferraz@gmail.com>

voltar para o topo