I read everything Aristotle Pagaltzis writes carefully. I often agree. You should too.

Aristotle responded to my practical/philosophical tirade against manual type checks in Perl 5 APIs with a comment that bears consideration:

Many objects are blessed hashes. However, most of the time, that is an implementation detail rather than an advertised part of the API... the question you should ask is not "can I treat this like a hash?" but "am I supposed to treat this like a hash?".

He's right. That's a potential design flaw in my suggestion to attempt to treat what should be a hash reference as a hash reference. Of course, the opposite design flaw is to disallow perfectly valid values that should work just fine if you treat them as hash references.

You get to pick which theoretical axe to grind there.

(Aristotle also recommends the use of UNIVERSAL::ref to allow objects and classes to provide their own ref() methods to return appropriate values. That's a good solution if you're working with code that uses the ref() technique to check for type appropriateness. If you're working with library code which uses a mishmash of all of the various techniques which catch some cases but not others... that's where the simplicity of eval { ... } shines for me. Do consider UNIVERSAL::ref , however. Along the same lines, Burak Gursoy noted that Scalar::Util::Reftype has a better API than reftype() from Scalar::Util .)

Your theoretical bias determines the way you write your APIs, even if you don't realize you have a theoretical bias.

If you take my approach, you give the programmer the responsibility of not passing in objects which shouldn't be dereferenced as hashes. If you pass in a blessed hash reference, my code assumes you intended it to work like a hash reference. Yes, you could pass in an object accidentally, but I prefer to allow people to do clever things (like passing in an overloaded object) when necessary, rather than forbidding them.

If you take the other approach, you give the programmer more safety against accidentally passing in the wrong thing unintentially while removing some possibility for cleverness that may be necessary in some cases. Please note: I'm not saying that this is what Aristotle himself prefers; I merely used his comment to illustrate this possibility.

My approach is not always right in every circumstance. I don't always use it in every circumstance. Yet I use it as a design principle: I don't want to forbid intelligent people from doing clever things I didn't intend because I didn't imagine a concrete use for them when I designed the API. Quite the opposite! I want people to use APIs I write to do things I couldn't imagine. That, to me, is a sign of success.

Some people will abuse them. Some people will misuse them. Good documentation and great examples help. (Modern Perl schadenfreude means shaking your head in disbelief when you see the dreadful my $io = new IO::Socket::INET->new( ... ) idiom repeated in 2009.)

Yet my experience writing copious tests for and maintaning plenty of Perl 5 code suggests that treating types checks as "What can you do?" not "How do you do it?" or "What are you?" improves genericity, improves reusability, and expands the possibilities for happy serendipities. I can't prevent inexperienced or bad or malicious coders from doing bad things with my APIs, but I can allow disciplined and smart and well-cultured programmers to do great things with them by not getting in their way.