¿Cómo puedo determinar el tipo de referencia bendita en Perl?
Pregunta
En Perl, un objeto es simplemente una referencia a cualquiera de los tipos de datos básicos de Perl que han sido bendecidos en una clase particular.Cuando utiliza la función ref() en una referencia no bendecida, se le indica a qué tipo de datos apunta la referencia.Sin embargo, cuando llama a ref() en una referencia bendecida, se le devuelve el nombre del paquete en el que se ha bendecido esa referencia.
Quiero saber el tipo subyacente real de la bendita referencia.¿Cómo puedo determinar esto?
Solución
Scalar::Util::reftype()
es la solución más limpia.El Scalar::Util
El módulo se agregó al núcleo de Perl en la versión 5.7 pero está disponible para versiones anteriores (5.004 o posteriores) desde CPAN.
También puedes sondear con UNIVERSAL::isa()
:
$x->isa('HASH') # if $x is known to be an object
UNIVERSAL::isa($x, 'HASH') # if $x might not be an object or reference
Obviamente, también tendrías que comprobar si ARRAY
y SCALAR
tipos.El módulo UNIVERSAL (que sirve como clase base para todos los objetos) ha sido parte del núcleo desde Perl 5.003.
Otra forma, fácil pero un poco sucia, es encadenar la referencia.Suponiendo que la clase no ha sobrecargado la cadena, obtendrá algo parecido Class=HASH(0x1234ABCD)
, que puedes analizar para extraer el tipo de datos subyacente:
my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i);
Otros consejos
Probablemente no deberías hacer esto.El tipo subyacente de un objeto es un detalle de implementación con el que no deberías meterte.¿Por qué querrías saber esto?
Y mi primer pensamiento sobre esto fue:"Los objetos en Perl siempre son referencias hash, entonces, ¿qué truco?"
Pero Scalar::Util::reftype es la respuesta.Gracias por poner la pregunta aquí.
Aquí hay un fragmento de código para demostrar esto.(por si a alguien le sirve de algo).
$> perl -e 'use strict; use warnings "all"; my $x = [1]; bless ($x, "ABC::Def"); use Data::Dumper; print Dumper $x; print ref($x) . "\n"; use Scalar::Util "reftype"; print reftype($x) . "\n"'`
Producción:
$VAR1 = bless( [ 1 ], 'ABC::Def' ); ABC::Def ARRAY