es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Error de Perl: Intento de “bless” en una referencia.

He estado trabajando con Perl orientado a objetos. Tengo una clase base, que es un código heredado y no puedo cambiarlo. Estoy escribiendo una clase derivada con un nuevo estilo (también conveniente para mí), pero cuando lo estoy derivando, estoy obteniendo un error como:

Intento de bendición en una referencia

Mi código es similar al siguiente código:

paquete Base;
sub nuevo {
    mi ($clase, %args) = @_;
    mi $self = {};

    $self->{top} = $args{top};
    volver a bendecir $auto, $clase;
}
1;

La clase derivada:

paquete derivada;
usar base qw{Base};
usar campos qw{_bot};

sub nuevo {

    my __PACKAGE__ $this = cambio;
    mi %arg = @_;

    a menos que (ref $this) {
        $this = campos::nuevo($esto);

    }
    $this->Base::nuevo( %arg);
    volver a bendecir $auto, $esto;
}
1;

El llamador es:

usar File::Basename;
COMENZAR {
  mi $dir_raíz = dirname $0;
  empujar(@INC, $dir_raíz);
}
usar derivado;
mi $d = nuevo derivado(top => "t1");

Estoy obteniendo el siguiente error:

Intento de bendición en una referencia en la línea Base.pm 8.
Tags:  ,

Answer

  1. Avatar for davy.ai

    El error está ocurriendo porque la clase Base está devolviendo una referencia no bendecida y la clase Derived está intentando bendecirla. Esto no está permitido en Perl.

    Para solucionar este problema, debes modificar el constructor de la clase Derived para crear un nuevo objeto de su propia clase utilizando la función fields::new en lugar de intentar reutilizar el objeto de la clase base. Luego, puedes llamar al constructor padre y pasar los argumentos utilizando la palabra clave SUPER.

    Aquí está el código modificado:

    package Derived;
    use base qw(Base);
    use fields qw(_bot);
    
    sub new {
        my $class = shift;
        my $self = $class->fields::new(); # crear un nuevo objeto de la clase derivada
        my %arg = @_;
    
        $self->SUPER::new(%arg); # llamar al constructor padre y pasar los argumentos
    
        return $self;
    }
    1;
    

    Ahora, cuando creas un nuevo objeto de la clase Derived, creará un nuevo objeto de su propia clase y llamará al constructor padre, lo que bendecirá el objeto en la clase Base.

    use File::Basename;
    BEGIN {
        my $root_dir = dirname $0;
        push(@INC, $root_dir);
    }
    use Derived;
    
    my $d = new Derived(top => "t1");
    

    Esto debería corregir el error y permitirte usar tu conveniente estilo orientado a objetos.

Comments are closed.