http://www.perlmonks.org?node_id=189485

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

Just a quick question -- what's the best (eg. fastest, least amount of code) way to test to see if a subroutine is defined in the current namespace?

I looked around here a bit, but couldn't find anyone else's comments on this. So I've been using eval, but I figure there must a perl shortcut for this sort of thing..

Here's what I've got:
my $sub_to_test = "test_sub"; # try to fire an EVAL_ERROR eval "$sub_to_test()"; # if no EVAL_ERROR if (!$@) { # do the thing eval "$sub_to_test ('testing, 1,2,3')"; } sub test_sub { return unless @_; print "TEST_SUB: $_[0]\n"; }

can I do any better?
--twerq

Replies are listed 'Best First'.
Re: test for subroutine existence
by Abigail-II (Bishop) on Aug 12, 2002 at 13:59 UTC
    To see whether something is defined, you use the defined function:
    #!/usr/bin/perl use warnings 'all'; use strict; sub my_sub {1} print "my_sub ", defined &my_sub ? "exists\n" : "doesn't exist\n"; print "no_sub ", defined &no_sub ? "exists\n" : "doesn't exist\n"; __END__ my_sub exists no_sub doesn't exist
    Abigail
      Sorry, I probably wasn't clear enough in my original post (but that's why I added the code)...
      I need to be able to test for a subroutine's existence, a subroutine who'se name is only available to me in a scalar -- so I can't very well use defined &my_sub (or can I?)

      fuzzyping's right, eval does work pretty well, except that I end up actually executing the subroutine itself just to see if it's there -- I'd prefer not to actually run it at test time...

      --twerq
        No eval needed.
        #!/usr/bin/perl use warnings 'all'; use strict; sub my_sub {1} foreach my $sub (qw /my_sub no_sub/) { print "$sub ", defined &$sub ? "exists\n" : "doesn't exist\n"; } __END__ my_sub exists no_sub doesn't exist
        Abigail
        Okay, anyway -- now it seems pretty obvious:
        print "my_sub ", test_for_sub("my_sub") ? "exists\n" : "doesn't exist\ +n"; print "no_sub ", test_for_sub("no_sub") ? "exists\n" : "doesn't exist\ +n"; sub test_for_sub { my ($expr) = @_; return eval "defined &$expr"; } sub my_sub { 1; }


        --twerq
Re: test for subroutine existence
by fuzzyping (Chaplain) on Aug 12, 2002 at 14:02 UTC
    Seems like eval() works fine for you, but, if you simply want to check for a sub's existence without having to perform a call on it, just use defined() (or the implied defined):

    You may also use defined(&func) to check whether subroutine &func has ever been defined. The return value is unaffected by any forward declarations of &foo. Note that a subroutine which is not defined may still be callable: its package may have an AUTOLOAD method that makes it spring into existence the first time that it is called -- see perlsub.

    -fp
Re: test for subroutine existence
by ehdonhon (Curate) on Aug 12, 2002 at 17:00 UTC

    As long as you are using a simple module with no inheritance, you could rely on can to do this:

    if ( __PACKAGE__->can( 'sub_to_test' ) ) { ... }
Re: Test for Subroutine Definition
by tadman (Prior) on Aug 15, 2002 at 07:42 UTC
    Just my two cents:
    sub foo { } foreach (qw[ foo bar ]) { print "$_? ",(defined(*$_{CODE})? "defined":"undef"), "\n"; }
    Using this kind of test, you can check for other stuff, like GLOB, filehandles and such, which aren't easily prefixed with something like '$', '&', '%' or '@'.