O que significa `$ haxixe {$ key} | = {}` fazer em Perl?
-
03-07-2019 - |
Pergunta
Eu estava lutando com alguns Perl que as referências usos hash.
No final descobriu-se que o meu problema era a linha:
$myhash{$key} |= {};
Isto é, "atribuir R $ myhash {$ key} uma referência a um hash vazio, a menos que já tem um valor".
Dereferencing isso e tentar usá-lo como uma referência de hash, no entanto, resultou em erros de intérprete sobre o uso de uma corda como uma referência hash.
alterá-lo para:
if( ! exists $myhash{$key}) {
$myhash{$key} = {};
}
... fez coisas trabalho.
Então, eu não tenho um problema . Mas estou curioso sobre o que estava acontecendo.
Alguém pode explicar?
Solução
A razão que você está vendo um erro sobre o uso de uma corda como uma referência hash é porque você está usando o operador errado. meios |=
"bitwise-or-Atribuir." Em outras palavras,
$foo |= $bar;
é o mesmo que
$foo = $foo | $bar
O que está acontecendo no seu exemplo é que a sua nova referência de hash anônimo está ficando Stringified, em seguida, bit a bit-ORed com o valor de $myhash{$key}
. Para confundir ainda mais as coisas, se $myhash{$key}
é indefinido no momento, o valor é o simples stringification da referência do hash, que parece HASH(0x80fc284)
. Então, se você fizer uma inspecção rápida da estrutura, pode olhar como uma referência de hash, mas não é. Está aqui alguma saída útil via Data::Dumper
:
perl -MData::Dumper -le '$hash{foo} |= { }; print Dumper \%hash'
$VAR1 = {
'foo' => 'HASH(0x80fc284)'
};
E aqui está o que você começa quando você usar o operador correto:
perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash'
$VAR1 = {
'foo' => {}
};
Outras dicas
Perl tem operadores de atribuição de taquigrafia. O operador ||=
é frequentemente usado para valores padrão definidos para as variáveis ??devido à característica de ter operadores lógicos retornar o último valor avaliado do Perl. O problema é que você usou |=
que é uma bit a bit ou em vez de ||=
que é uma lógica ou.
Como de Perl 5.10 é melhor uso //=
vez. //
é a lógica definida pelo ou do operador e não falha no caso canto onde o valor atual está definido, mas falsa.
Eu acho que o problema estava usando "|=
" (bit a bit-ou cessão) em vez de "||=
" (Atribuir se falso).
Note que o novo código não é exatamente equivalente. A diferença é que "$myhash{$key} ||= {}
" irá substituir valores existentes-mas-falsas com uma referência de hash, mas o novo não. Na prática, isso provavelmente não é relevante.
Tente isto:
my %myhash;
$myhash{$key} ||= {};
Você não pode declarar um hash elemento em uma cláusula my
, tanto quanto eu sei. Você declara o hash em primeiro lugar, em seguida, adicionar o elemento.
Edit: Eu vejo que você tenha tomado a my
. Que tal experimentar ||=
vez de |=
? O primeiro é idiomática para inicialização "preguiçoso".