Maldita sea, Perl no puede bendecir mi objeto
Pregunta
Dejando de lado los juegos de palabras, estoy tratando de implementar un método import
en mi clase Perl para crear una instancia de un objeto Data
, que es esencialmente una matriz glorificada de hashrefs, a partir de una matriz adecuada de hashrefs.
Aquí tienes un ejemplo de cómo planeo usarlo:
# 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
Mi implementación de import
es la siguiente:
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;
Lo sorprendente es que Perl informa del error en el tiempo de compilación (observe el bloque BEGIN
):
Can't bless non-reference value at Data.pm line 51.
BEGIN failed--compilation aborted at myScript.pl line 8.
perldiag
no aportó mucha claridad a lo que está sucediendo:
No se puede bendecir el valor que no es de referencia
(F)
Solo las referencias duras pueden ser bendecidas. Así es como Perl "aplica" encapsulación de objetos. Verperlobj
.
Incluso intenté inicializar el objeto y agregar los datos en dos pasos separados:
sub import { #< Another constructor >
my ( $class, $data ) = @_;
my $obj = $class->initialize;
push @$obj, @$data;
return $obj;
}
Esto resultó en el siguiente error en tiempo de compilación:
Can't use an undefined value as an ARRAY reference...
BEGIN failed--compilation aborted at...
Dos preguntas:
- ¿Qué hay de malo en lo que hice?
- ¿Podría alguien aclarar la explicación
perldiag
de este error en tiempo de compilación?
Solución
import () es un nombre peligroso para un método, ya que Perl a veces llama a un método llamado 'import'.De hecho, la declaración:
use Data;
realmente significa:
BEGIN {
require Data;
Data->import();
}
que ocurre durante la "compilación".
Por lo tanto, es probable que Perl llame a su método import () como parte del mecanismo de carga de clases antes de que tenga la oportunidad de usarlo.Debería cambiar el nombre de su método import () a otra cosa (por ejemplo, import_data) y debería estar bien.