I am receiving a hash of hashes from another function, and some elements of the hash of hashes can be another hash. How can I test to see if something is a hash?
+6
A:
Use ref
function:
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}
Ivan Nevostruev
2010-09-24 16:56:22
This test doesn't work for hash-like objects: `$r={};bless $r,"fail";print ref $r`
mobrule
2010-09-24 17:01:39
I don't think violating object encapsulation is a good idea.
Ivan Nevostruev
2010-09-24 17:03:21
+13
A:
Depending on what you want you will need to use ref
or reftype
(which is in Scalar::Util
, a core module). If the reference is an object, ref
will return the class of the object instead of the underlying reference type, reftype
will always return the underlying reference type.
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";
}
Chas. Owens
2010-09-24 17:10:00
@brian d foy Are you unfamiliar with the word "tf"? It is like "if", but more so.
Chas. Owens
2010-09-24 17:36:58
@Chas. Owens - I thought **emphatic if** was "iiiif", or perlishly: `'i'x$n.'f'` (for $n > 1)
Mike Ellery
2010-09-24 21:34:41
+2
A:
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 );
* through overload
You probably do not need the last one, though.
see Params::Util
Axeman
2010-09-24 18:37:40
`Params::Util::_HASHLIKE` calls `Scalar::Util::reftype`, but it also checks to see if its argument is overloading the hash-dereferencing operator -- this detects objects that can pretend to be hashrefs even when they are not really hashrefs.
mobrule
2010-09-24 18:48:26
@mobrule: Yeah, I know. I just thought presenting two choices would drive him to the link to see the difference. I added a note saying that he probably doesn't need it.
Axeman
2010-09-24 19:36:10
+1
A:
I've always used isa
, but if the thing being tested isn't an object (or might not be an object), you need to call it as the function UNIVERSAL::isa
:
if ( UNIVERSAL::isa( $var, 'HASH' ) ) { ... }
Joe
2010-09-24 18:45:08