rapide has asked for the wisdom of the Perl Monks concerning the following question:

I want to load a module dynamically and at the same time check if a particular function exists. How would I do this? e.g. code below:

require('perlmonk.pm'); if(defined 'perlmonk'->funnyfunction()) { print "YES it DOES exist!"; } else { print "NO, it does NOT exist!"; }

Replies are listed 'Best First'.
Re: How to check if a function exists within a package?
by ikegami (Patriarch) on Sep 08, 2008 at 01:06 UTC

    For functions, defined.

    if ( defined( &perlmonk::funnyfunction ) )

    For methods, can. Checks inheritance.

    if ( perlmonk->can('funnyfunction') )
    if ( $obj->can('funnyfunction') )
      if ( defined( &perlmonk::funnyfunction ) )

      Why wouldn't that call the function passing in @_ and check defined on the result? I mean, I see that it doesn't do that, but why? You have to put the ()'s on the end of it to get what I'd expect.

      -Paul

        It's just another special parsing rule. exists and goto are exactly the same, but they are hardly the only three functions that have special parsing rules. map's curlies don't create a hash. print's file handle isn't a function name. And the list goes on.
      Great answer. Since I had methods it was the right answer to use can. Thanks everyone!
Re: How to check if a function exists within a package?
by GrandFather (Saint) on Sep 08, 2008 at 01:12 UTC

    To check if something exists use exists. ;)

    use strict; use warnings; require ('Encode.pm'); if (exists &Encode::encode) { print "Exists\n"; } else { print "None such\n"; }

    Prints:

    Exists

    Perl reduces RSI - it saves typing

      defined vs exists:

      sub foo {} sub bar; my @names = qw( foo bar baz ); local $, = "\t"; local $\ = "\n"; print('', @names); print('exists', map { exists(&$_) ?1:0 } @names); print('defined', map { defined(&$_) ?1:0 } @names);
      foo bar baz exists 1 1 0 defined 1 0 0

      You can't call the ones that exist but aren't defined, so defined is probably a better choice.

      >perl -e"sub bar; bar()" Undefined subroutine &main::bar called at -e line 1.
Re: How to check if a function exists within a package?
by codeacrobat (Chaplain) on Sep 08, 2008 at 18:55 UTC
    I prefer a symbol table lookup.
    perl -e ' package Foo; sub bar{42}; package main; print defined *Foo::bar{CODE}' 1
    This avoids ambiguity issues with using the ampersand.

    print+qq(\L@{[ref\&@]}@{['@'x7^'!#2/"!4']});
      why not: sub method_exists_in_obj($$) { my $obj = shift;#object as href my $method = shift;#method name to test for return 1 if (defined(&{(ref $obj)."::".$method})); return 0; }