I get awfully tired of writing this:
use Scalar::Util 'blessed';
if ( blessed($thing) && $thing->can('do_something') ) { ... }
Which is why I'm awfully tempted to just write this almost throwaway code and put it on the CPAN. I probably won't, but I toy with the idea.
package Can;
use strict;
use warnings;
use Scalar::Util 'blessed';
use base 'Exporter';
@EXPORT = 'Can';
sub Can {
my ($object, $method) = @_;
return unless blessed $object;
return $object->can($method);
}
1;
And in my code:
use Can; # use Can () if you don't want importing
if ( Can( $thing, 'do_something' ) ) { ... }
Depending upon the type of code you write, it's quite easy to get an unblessed reference instead of an object. I get tired of always having to use blessed from Scalar::Util, but this is a common enough practice (I hit a lot in exception handling, for example) that it seems like a "write it and forget it" module might be useful.
And for those who do UNIVERSAL::can($object, $method), don't. If the object overrides &can, you're in trouble. If you already know your objects don't override &can, then you're relying on implementation details that you shouldn't be relying on.
Re:This is also an API problem
chromatic on 2006-01-24T22:33:07
What if
$objectcontains a class name?Re:This is also an API problem
jk2addict on 2006-01-24T22:50:16
Then return true. It's not telling a lie.
$classname->foo and &classname::foo exists, and can be called. How they are supposed to be called is up to the module author and consumer, and not the concern of can.Re:This is also an API problem
chromatic on 2006-01-25T03:11:38
I simply mean that there isn't a single use for
UNIVERSAL::canthat makes a replacement easy to write.UNIVERSAL::isais even worse.
withUNIVERSAL::can($object, 'method')
. It Just Works.eval { $object->can('method') }
Re:Simpler means
Alias on 2006-01-25T01:16:06
Unless ->can throws an exception, in which case you get a false negative...
I really need to get around to adding _CAN to Params::Util:/
Re:Simpler means
merlyn on 2006-01-25T01:33:10
well, if it threw an exception, it probably can't do that then. {grin}