in reply to Overloading ref() just like ->isa and ->can?

What would be the best practice method for determining if something is a hash or array? At times I want to know that the underlying object is a hashref, even if it has been blessed. e.g.
use strict; use warnings; { package foo; sub new { bless {}, shift}; } my $foo = foo->new(); print "ref(foo) = ",ref($foo), "\n"; print "foo is a hash\n" if UNIVERSAL::isa($foo,'HASH'); my $bar = {a => 1}; # The following won't work # print "bar is a hash\n" if $bar->isa('HASH'); print "bar is a hash\n" if UNIVERSAL::isa($bar,'HASH');
  • Comment on Re: Overloading ref() just like ->isa and ->can - best practice for isa(HASH)?
  • Download Code

Replies are listed 'Best First'.
Re^2: Overloading ref() just like ->isa and ->can - best practice for isa(HASH)?
by diotalevi (Canon) on Aug 22, 2006 at 19:12 UTC

    If you want to know whether it really, truely is a hash, see if SVt_PVHV is true for the SV. See sv.h for the dirt.

    use B qw( svref_2object SVt_PVHV ); sub is_hash { my $ref = shift @_; return ref( $ref ) and svref_2object( $ref ) & SVt_PVHV; }

    If you just want to know whether it supports being treated like a hash, do something akin to a ->can test for hash-ness. If the hash dereference doesn't die, then $ref acts like a hash.

    sub does_hash { my $ref = shift @_; return ref( $ref ) and eval { %$ref; 1 }; }

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊