Dannazione, Perl non può benedire il mio oggetto
Domanda
Giochi di parole a parte, sto cercando di implementare un metodo import
nella mia classe Perl per istanziare un oggetto Data
, che è essenzialmente un array glorificato di hashref, da un corretto array di hashref.
Ecco un esempio di come intendo utilizzarlo:
# 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
La mia implementazione import
è la seguente:
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;
La cosa sorprendente è che Perl riporta l'errore in fase di compilazione (nota il blocco BEGIN
):
Can't bless non-reference value at Data.pm line 51.
BEGIN failed--compilation aborted at myScript.pl line 8.
perldiag
non ha aggiunto molta chiarezza a quello che sta succedendo:
Non posso benedire un valore non di riferimento
(F)
Possono essere benedetti solo riferimenti concreti. Questo è il modo in cui Perl "impone" incapsulamento di oggetti. Vedereperlobj
.
Ho anche provato a inizializzare l'oggetto e ad aggiungere i dati in due passaggi separati:
sub import { #< Another constructor >
my ( $class, $data ) = @_;
my $obj = $class->initialize;
push @$obj, @$data;
return $obj;
}
Ciò ha provocato il seguente errore in fase di compilazione:
Can't use an undefined value as an ARRAY reference...
BEGIN failed--compilation aborted at...
Due domande:
- Cosa c'è di sbagliato in quello che ho fatto?
- Qualcuno potrebbe chiarire la spiegazione
perldiag
di questo errore in fase di compilazione?
Soluzione
import () è un nome pericoloso da dare a un metodo, poiché Perl a volte chiama un metodo chiamato 'import' per te.In effetti, l'affermazione:
use Data;
significa davvero:
BEGIN {
require Data;
Data->import();
}
che accade durante la "compilazione".
Quindi è probabile che il tuo metodo import () venga chiamato da Perl come parte del meccanismo di caricamento della classe prima che tu abbia la possibilità di usarlo.Dovresti rinominare il tuo metodo import () con qualcos'altro (ad esempio import_data) e dovresti stare bene.