O que acontece nessas linhas de uso do Perl?
-
21-09-2019 - |
Pergunta
Não entendo o que acontece aqui:
use PAR { file => 'foo.par', fallback => 1 };
Acho que é um hash anônimo.Como um módulo está usando-o do use
linha?Você pode lançar alguma luz?
EDITAR:Não estou interessado no módulo PAR.Só estou interessado em saber como isso funciona nos bastidores.Como posso configurar meus módulos assim?
Solução
Mais basicamente, é isso que a sintaxe engraçada do hashref faz (usando Uso do PerlDoc -f como referência):
Diga que temos este módulo básico (coloque -o em Foo.pm
no seu diretório atual):
package Foo;
use Data::Dumper;
sub import
{
print "import was passed these arguments: ". Dumper(\@_);
}
1;
Quando ligamos perl -I. -wle'use Foo { a => 1, b => 2}'
, o código Foo->import({a=>1, b=>2})
É executado. Então é isso que obtemos como saída:
import was passed these arguments: $VAR1 = [
'Foo',
{
'a' => 1,
'b' => 2
}
];
Basicamente, essa sintaxe nos permite fazer magia com o Exportador, mas na verdade você pode fazer import()
Faça o que quiser (certifique -se de documentar muito para não causar confusão!)
Outras dicas
Quando você use
Um módulo, você pode passar uma lista de argumentos para ele. No seu exemplo (que parece ter um erro de digitação, perdendo uma cotação final), uma lista com um elemento (uma referência de hash) é aprovada.
De forma geral:
use Module LIST
Torna -se o seguinte:
BEGIN {
require Module;
Module->import( LIST );
}
o BEGIN
O Block garante que todo o material aconteça no tempo de compilação. o require
Carrega o módulo na memória, se ainda não estiver lá. E então o módulo import()
o método é chamado com quaisquer argumentos aprovados (como LIST
) no original use
declaração.
Para que seus próprios módulos façam algo com tal LIST
de argumentos, seu módulo precisaria definir um import()
método. Muitos módulos não fazem isso; Em vez disso, eles herdam import()
de Exporter
classe. Ver Uso do PerlDoc -f para mais detalhes.
Se o seu módulo define o seu próprio import()
Método, você precisará exportar símbolos para o código do cliente ou, mais comumente, usar o export_to_level()
método fornecido por Exporter
. O primeiro argumento a esse método é um número inteiro positivo, especificando o nível na pilha de chamadas para a exportação de símbolos. O valor mais comum de 1 significa exportar símbolos um nível acima de O pacote atual - isto é, para o código do cliente que está usando seu módulo. Aqui está um esboço do que você import()
o método precisaria fazer.
sub import {
my ($class, @args) = @_;
# Do whatever you need to do with the LIST of arguments
# supplied by the client code using your module.
# Let Exporter do its normal work of exporting symbols
# into the client code using your module.
$class->export_to_level(1, @_);
}
Sim, isso é um hash anônimo. É passado como um argumento para os módulos import
método.
O PAR é o módulo CPAN Kit de ferramentas de arquivo perl.. O hashref está sendo transmitido por parâmetros de configuração para o par.
O código:
use PAR { file => 'foo.par, fallback => 1 };
use Foo::Bar;
significa usar Foo::Bar
se estiver disponível, mas volta a usar o arquivo "foo.par
"(que presumivelmente possui uma versão arquivada de Foo::Bar
).
Resposta direta à sua pergunta:PAR faz isto (linha 340):
# called on "use PAR"
sub import {
my $class = shift;
[...]
my @args = @_;
[...]
# process args to use PAR 'foo.par', { opts }, ...;
foreach my $par (@args) {
if (ref($par) eq 'HASH') { # <---- This is what handle's your case!
# we have been passed a hash reference
_import_hash_ref($par);
}
elsif ($par =~ /[?*{}\[\]]/) {
# implement globbing for PAR archives
[...]
}
else {
# ordinary string argument => file
[...]
}
}
Agora, infelizmente, depois de se aprofundar no que realmente está acontecendo lá, você perceberá que escolheu um dos módulos mais complicados do CPAN como exemplo para aprender, então sugiro que você dê uma olhada no boa documentação sobre módulos.Para lhe dar um guia sobre o que procurar:Quando você "usa" um módulo e fornece argumentos para a instrução use, o perl carrega o módulo e chama seu método "import" com a lista de argumentos.
No seu caso de exemplo, há simplesmente um argumento:Uma referência a um hash.A sintaxe {key=>"value",key2=>"value2",...} é o construtor para hashes anônimos.Estes estão documentados em a página de manual do perlref, mas explicado em termos mais amigáveis em o tutorial perlreftut.