Droga, Perl não pode abençoar meu objeto
Pergunta
Piadas à parte, estou tentando implementar um método import
em minha classe Perl para instanciar um objeto Data
, que é essencialmente uma matriz glorificada de hashrefs, a partir de uma matriz adequada de hashrefs.
Aqui está um exemplo de como pretendo usá-lo:
# Pull in the data
my $data = Data->import(
[
{ a => 1, b => 7, c => 3},
{ a => 7, b => 9, c => 2},
]
);
$data->manipulate; # Use package methods
Minha implementação import
é a seguinte:
package Data;
sub initialize {
my $class = shift;
my $data = [];
bless $data, $class;
return $data;
}
sub import {
my ( $class, $data ) = @_;
bless $data, $class;
return $data;
}
1;
O surpreendente é que Perl relata o erro em compile -time (observe o bloco BEGIN
):
Can't bless non-reference value at Data.pm line 51.
BEGIN failed--compilation aborted at myScript.pl line 8.
perldiag
não acrescentou muita clareza ao que está acontecendo:
Não é possível abençoar valores sem referência
(F)
Apenas referências físicas podem ser abençoadas. É assim que Perl "impõe" encapsulamento de objetos. Verperlobj
.
Até tentei inicializar o objeto e adicionar os dados em duas etapas diferentes:
sub import { #< Another constructor >
my ( $class, $data ) = @_;
my $obj = $class->initialize;
push @$obj, @$data;
return $obj;
}
Isso resultou no seguinte erro de tempo de compilação:
Can't use an undefined value as an ARRAY reference...
BEGIN failed--compilation aborted at...
Duas perguntas:
- O que há de errado com o que eu fiz?
- Alguém poderia esclarecer a explicação
perldiag
desse erro em tempo de compilação?
Solução
import () é um nome perigoso para dar um método, já que o Perl às vezes chama um método chamado 'import' para você.Na verdade, a declaração:
use Data;
realmente significa:
BEGIN {
require Data;
Data->import();
}
o que acontece durante a 'compilação'.
Portanto, é provável que seu método import () esteja sendo chamado por Perl como parte do mecanismo de carregamento de classe antes que você tenha a chance de usá-lo.Você deve renomear seu método import () para outra coisa (por exemplo, import_data) e você deve ficar bem.