2010-09-24 2 views
19

Ich erhalte einen Hash von Hashes von einer anderen Funktion, und einige Elemente des Hashs von Hashes können ein anderer Hash sein. Wie kann ich testen, ob etwas ein Hash ist?Wie kann ich testen, dass "etwas" ein Hash in Perl ist?

+2

mögliche Duplikate von [Wie kann ich feststellen, welcher Werttyp in einer Perl-Variablen enthalten ist?] (Http://stackoverflow.com/questions/1731333/how-do-i-tell-what-type-of-value -is-in-a-perl-variable) – Ether

Antwort

36

Je nachdem, was Sie wollen, Sie ref oder reftype (das ist in Scalar::Util, ein Kernmodul) verwendet werden müssen. Wenn die Referenz ein Objekt ist, gibt ref die Klasse des Objekts anstelle des zugrunde liegenden Referenztyps zurück, reftype gibt immer den zugrunde liegenden Referenztyp zurück. obwohl

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 Kennen Sie das Wort "tf" nicht? Es ist wie "wenn", aber mehr. –

+1

Also, eine stärkere Version von if? Gibt es auch eine schwächere Version? –

+1

@brain d foy Ja, es gibt "ɨf". –

10

Verwenden ref Funktion:

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

Dieser Test funktioniert nicht für Hash-ähnliche Objekte: '$ r = {}; segne $ r," fail "; print ref $ r' – mob

+4

Ich denke nicht verletzend Objektverkapselung ist eine gute Idee. –

+0

Es gibt auch einige falsche Positive hier. '$ array = []; segne $ array, 'HASH'; print ref $ array; 'druckt' HASH'. Nicht dass du das jemals tun solltest. –

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); 

* overload durch

Sie die letzte wahrscheinlich nicht brauchen.

siehe Params::Util

+2

'Params :: Util :: _ HASHLIKE' ruft 'Scalar :: Util :: reftype' auf, prüft aber auch, ob sein Argument den Hash-Dereferenzierungsoperator überlastet - dies erkennt Objekte, die sich als Hashrefs ausgeben können, selbst wenn es sich nicht wirklich um Hashrefs handelt. – mob

+0

@mobrule: Ja, ich weiß. Ich dachte nur, zwei Möglichkeiten zu präsentieren würde ihn zum Link führen, um den Unterschied zu sehen. Ich fügte eine Notiz hinzu, dass er es wahrscheinlich nicht brauche. – Axeman

5

ich immer isa verwendet haben, aber wenn die Sache geprüft wird kein Objekt ist (oder auch nicht ein Objekt sein), können Sie es wie die Funktion UNIVERSAL::isa aufrufen müssen:

if (UNIVERSAL::isa($var, 'HASH')) { ... } 
Verwandte Themen