2008-08-14 19 views
18

En Perl, un objeto es solo una referencia a cualquiera de los tipos básicos de datos de Perl que han sido bendecidos en una clase en particular. Cuando utiliza la función ref() en una referencia no autorizada, se le indica a qué tipo de datos apunta la referencia. Sin embargo, cuando llamas a ref() en una referencia bendita, se te devuelve el nombre del paquete en el que se ha bendecido la referencia.¿Cómo puedo determinar el tipo de referencia bendecida en Perl?

Quiero saber el tipo subyacente real de la referencia bendita. ¿Cómo puedo determinar esto?

Respuesta

18

Scalar::Util::reftype() es la solución más limpia. El módulo Scalar::Util se agregó al núcleo de Perl en la versión 5.7, pero está disponible para versiones anteriores (5.004 o posterior) de CPAN.

También puede 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ía que comprobar si hay ARRAY y SCALAR tipos. El módulo UNIVERSAL (que sirve como la 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 codificar la referencia. Suponiendo que la clase no se ha sobrecargado stringification que pondremos en algo parecido a Class=HASH(0x1234ABCD), que se puede analizar para extraer el tipo de datos subyacente:

my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i); 
+3

Solo quiere eval {$ x-> isa ($ type)}; Si eso no es un objeto, devuelve falso. Si no es del tipo correcto, obtienes falso, y si es del tipo correcto, te haces verdadero. :) –

2

Y mi primer pensamiento sobre esto fue: "Los objetos en Perl siempre son referencias hash, entonces, ¿qué es el truco?"

Pero, Scalar :: Util :: reftype es la respuesta. Gracias por hacer la pregunta aquí.

Aquí hay un fragmento de código para probar esto ... (en caso de que sea de alguna utilidad para cualquiera).

 
$> 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"'` 

Salida:

 
$VAR1 = bless([ 
       1 
       ], 'ABC::Def'); 
ABC::Def 
ARRAY 
+3

objetos a menudo se implementan como referencias de hash, pero no es un requisito. Un objeto puede ser cualquier tipo de referencia. –

6

Es probable que no debe hacer esto. El tipo subyacente de un objeto es un detalle de implementación con el que no debe meterse. ¿Por qué querrías saber esto?

+0

Estoy de acuerdo, y sabía que alguien haría este comentario. Realmente solo necesitaba esto al tratar de descubrir una estructura que estaba creando un módulo para poder modificar el módulo. Quería eliminar una clave particular de cualquier hash en la estructura porque contenía un JPEG sin procesar. –

+2

Más tarde descubrí que podía usar Data :: Dumper :: sortkeys para filtrar estos datos, de modo que Data :: Dumper no produjera megabytes de salida binaria. –

Cuestiones relacionadas