2010-09-24 14 views
19

Estoy recibiendo un hash de hashes de otra función, y algunos elementos del hash de hash pueden ser otro hash. ¿Cómo puedo probar para ver si algo es un hash?¿Cómo puedo probar que "algo" es un hash en Perl?

+2

posible duplicado de [¿Cómo puedo saber qué tipo de valor hay en una variable Perl?] (Http://stackoverflow.com/questions/1731333/how-do-i-tell-what-type-of-value -is-in-a-perl-variable) – Ether

Respuesta

36

Dependiendo de lo que quiere usted tendrá que utilizar ref o reftype (que está en Scalar::Util, un módulo básico). Si la referencia es un objeto, ref devolverá la clase del objeto en lugar del tipo de referencia subyacente, reftype siempre devolverá el tipo de referencia subyacente.

if (ref $var eq ref {}) { 
    print "$var is a hash\n"; 
} 

use Scalar::Util qw/reftype/; 

if (reftype $var eq reftype {}) { 
    print "$var is a hash\n"; 
} 
+3

@brian d foy ¿No estás familiarizado con la palabra "tf"? Es como "si", pero más aún. –

+1

Entonces, ¿una versión más fuerte de si? ¿Hay una versión más débil también? –

+1

@brain d foy Sí, hay "ɨf". –

10

Uso ref función:

ref($hash_ref) eq 'HASH' ## $hash_ref is reference to hash 
ref($array_ref) eq 'ARRAY' ## $array_ref is reference to array 

ref($hash{$key}) eq 'HASH' ## there is reference to hash in $hash{$key} 
+2

Esta prueba no funciona para los objetos tipo hash: '$ r = {}; bless $ r," fail "; print ref $ r' – mob

+4

No creo violando encapsulación de objetos es una buena idea. –

+0

También hay algunos falsos positivos aquí. '$ array = []; bless $ array, 'HASH'; print ref $ array; 'prints' HASH'. No es que nunca deberías hacer esto. –

3
use Params::Util qw<_HASH _HASH0 _HASHLIKE>; 

# for an unblessed hash with data 
print "$ref is a hash\n" if _HASH($ref); 
# for an unblessed hash empty or not 
print "$ref is a hash\n" if _HASH0($ref); 
# for a blessed hash OR some object that responds as a hash* 
print "$ref is hashlike\n" if _HASHLIKE($ref); 

* a través overload

Es probable que no necesita la última, sin embargo.

ver Params::Util

+2

'Params :: Util :: _ HASHLIKE' llamadas' Scalar :: Util :: reftype', pero también comprueba si su argumento está sobrecargando el operador hash-dereferencing - esto detecta objetos que pueden pretender ser hashrefs incluso cuando no son realmente hashrefs. – mob

+0

@mobrule: Sí, lo sé. Solo pensé que presentar dos opciones lo llevaría al enlace para ver la diferencia. Agregué una nota diciendo que probablemente no lo necesita. – Axeman

5

Siempre he usado isa, pero si lo que se está probando no es un objeto (o puede que no sea un objeto), es necesario llamar a la función UNIVERSAL::isa:

if (UNIVERSAL::isa($var, 'HASH')) { ... } 
Cuestiones relacionadas