[OT] best way to determine existence of a function in a package

Jonathan Rockway jon at jrock.us
Mon Nov 19 21:19:05 GMT 2007

On Mon, 2007-11-19 at 11:16 +0000, Paul LeoNerd Evans wrote:
> You don't need a reference. I've always found that UNIVERSAL::can() works
> just as well:
>   if( my $subref = UNIVERSAL::can( "Package", "function" ) ) {
>      $subref->( args, here );
>   }

Everyone was quick to jump down your throat on this one, so I thought
I'd explain why.  Consider this case:

   package My::Module;
   our $AUTOLOAD;
   sub AUTOLOAD { return 42 if $AUTOLOAD =~ /forty_?two/ }

Now you have some calling code that wants to see if My::Module can
"fortytwo", it will say something like "My::Module->can('fortytwo')" and
get undef back, since there is no fortytwo method in your module.  You
can rectify the situation by defining can:

  sub My::Module::can {
     return sub { $_[0]->forty_two } if $_[1] =~ /forty_?two/;

Now My::Module->can('fortytwo') will return true, and all is well!
However, if you called UNIVERSAL::can('My::Module', 'fortytwo'), your
My::Module::can would never get called, and hence the can call would
return inaccurate results.

Anyway, please read man UNIVERSAL and UNIVERSAL::isa (the CPAN version)
for more information.

Jonathan Rockway

More information about the london.pm mailing list