reftype() lazziness

I was doing a lot of foo() if ref($thing) eq 'ARRAY' or foo() if ref($thing) eq 'HASH' (even something idiotic like foo() if ref($thing) && "$thing" =~ m{.+?=HASH(0x.+?)}) checks inside a pet project of mine. So thought about making it in an elegant way instead. I mean ref($thing)->array or even ref($thing)->is_array seemed much better as a syntactic sugar. However ref() is clearly not the way to go for the implementation as it fails to identify the underlying type of objects. So, the obvious choice is Scalar::Util::reftype. I've named the module Scalar::Util::Reftype. In a way, I can say that it's similar to File::stat. Btw, Scalar::Util::reftype has one oddity: unlike CORE::ref it returns undef if you pass a non-ref parameter to it. So, instead of foo() if reftype($thing) eq 'ARRAY' one must say foo() if defined reftype($thing) && reftype($thing) eq 'ARRAY' or just foo() if reftype($thing) && reftype($thing) eq 'ARRAY' to prevent an annoying warning:

Fortunately, perl 5.10 comes with re::is_regexp to detect if an object is based on a regex or not. But what about older perls? We can remedy the situation with the help of Data::Dump::Streamer::regex under at least perl 5.8.x. Unfortunately Data::Dump::Streamer seems to fail under anything older than that. I wasn't aware that re::is_regexp is a new functionality until reached "ref() and Regexp" discussion on PerlMonks.

I also checked ref documentation. As of perl 5.10 it lists these reference types:

SCALARARRAYHASHCODEREFGLOBLVALUEFORMATIOVSTRINGRegexp

Only perl 5.10's ref seems to detect VSTRING refs and since they are deprecated and the usage seems to be rare, the module does not support them. Also FORMAT is only available in perl 5.8 and newer. But frankly, I can't imagine anyone creating refs/objects based on LVALUE, FORMAT or VSTRING (hmmm... maybe only TheDamian). So, they exist only for the sake of compatibility. For the Regexp type, I've just added a dynamic dependency on Data::Dump::Streamer if Scalar::Util::Reftype is tried to be installed under anything older than perl 5.10.

The interface is simple. Just use the module to get a brand new reftype function:

use Scalar::Util::Reftype;

foo() if reftype( "string" )->hash; # foo() will never be called
bar() if reftype( \$var )->scalar; # bar() will be called
baz() if reftype( [] )->array; # baz() will be called
xyz() if reftype( sub {} )->array; # xyz() will never be called

Here, class can be thought as analogous to Scalar::Util' s blessed function. It returns the package/class name of the reference if it happens to be a blessed reference. The rest of the methods test if the parameter matches the type they define.

Oh, I've also overloaded the object Scalar::Util::Reftype:reftype returns, to be sure that it will not be used in boolean contexts. If one makes such a thing, then the code will suffer the consequences:)

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Without JavaScript enabled, you might want to
use the classic discussion system instead. If you login, you can remember this preference.

Please Log In to Continue

I'm biased - I wrote UNIVERSAL::ref. I think you should be writing $thing->is_array instead of ref($thing)->is_array or Scalar::Util::reftype($thing)->is_array. That is, the thing itself should be responsible for telling you about itself and not some external bit of code.

I trend toward the Smalltalk end of the idea spectrum and I'd prefer that $thing be able to respond for itself. Outsourcing introspection prevents $thing from being able to intelligently decide to answer the question *differently*