in reply to RE: RE: Answer: How do I test if a
in thread How do I test if a 'thing' is a hash (or array or scalar)?

I was curious so I benchmarked the different approaches:

"HASH" eq ref($_) /HASH/ /(^|=)HASH\b/ UNIVERSAL::isa( $_, "HASH" )

If you have 20,000 references that you want to validate, then you might be able to notice that one of these methods takes 1/50 of a second to do all 20,000 while another takes 1/10 of a second. The first can be done about 1 million times per second, the middle 2 about 100,000 times per second, and the last about 500,000 times per second. I don't consider this difference something worth worrying about. (:

So UNIVERSAL::isa() is not a pig (and I didn't have to read the source code, yeah).

A comment I expected but only got in private is that doing anything other than "HASH" eq ref($r) is "looking inside the object" and should be avoided. I actually agree with the spirit of that criticism. If you are doing this to figure out how an object is internally implemented, then you deserve to have your code break when that object's implementation is updated. But I really don't think that that is the way something like this is likely to be used. In fact, I feel strongly that using "HASH" eq ref($r) is a bad thing because it breaks objects that it shouldn't!

If I have code that does something interesting with a hash via a reference, then I probably should (and may even need to) check whether I actually was given a reference to a hash. But I shouldn't refuse to work just because the reference to a hash that was given to me happened to be blessed.

Why should I make it difficult for someone to write:

use Hash::FindKeys qw( FindHashKeys ); # FindHashKeys finds keys of a hash where the key and # corresponding value meet certain criteria. Note that # ref($_[0]) must be "HASH" or it dies! [...] sub someMethod { my( $self )= shift @_; my @opts= FindHashKeys( $self, sub { /^-/ }, sub { $_ ne "" } ); # Oops, that dies! }
I shouldn't. And there are several other cases that come to mind like this, but I've rambled on long enough.

        - tye (but my friends call me "Tye")