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

Ok. I'm feeling stupid. I know I can do a can to determine if an object can call that method, but how do I check to see if a subroutine has already been defined in a given package?

------
We are the carpenters and bricklayers of the Information Age.

Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

  • Comment on Checking if a subroutine has been defined in a package...

Replies are listed 'Best First'.
Re: Checking if a subroutine has been defined in a package...
by suaveant (Parson) on Oct 09, 2001 at 22:55 UTC
    I believe defined will do the trick...
    if(defined &bar::foo) # or package bar; if(defined &foo)

                    - Ant
                    - Some of my best work - Fish Dinner

Re: Checking if a subroutine has been defined in a package...
by pjf (Curate) on Oct 11, 2001 at 04:27 UTC
    G'day dragonchild,

    Easy! You can use typeglobs, like this:

    if (*package::foo{CODE}) { # Function package::foo exists. } else { # Function package::foo does not exist. }
    Of course, if you want to check if an arbitary function exists, it's not quite as pretty:
    my $function = "package::foo"; { no strict qw/refs/; # We're going to use symbolic refs. if (*{$function}{CODE}) { # Function in $fuction exists. } else { # Function in $function does not exist. } }
    Hope that you find the above useful.

    Cheers,
    Paul

Re: Checking if a subroutine has been defined in a package...
by herveus (Prior) on Oct 11, 2001 at 20:26 UTC
    Howdy!

    CAVEAT: this is off the cuff and untested...

    Consider:

    my $foo = bless {}, 'package::name'; $foo->can('function');
    That is, bless something into the namespace you are checking and use that object to try 'can' against.

    UPDATE:

    Reading Re: Re (tilly) 1: Strict, strings and subroutines by merlyn, I see where this needs to not search ISA, leading (by way of cribbing)

    do { local @ISA; my $foo = bless {}, 'package::name'; $foo->can('function'); };

    yours,
    Michael

Re: Checking if a subroutine has been defined in a package...
by dragonchild (Archbishop) on Oct 12, 2001 at 22:30 UTC
    Ok. I've been trying to do
    Do something if defined &{"$package::$funcName"};
    and it's not working. Here's the situation:
    • In package A, I've got a function foo() which defines the subroutines, supposedly as needed.
    • In package B, which inherits (at some distance) from package A, I've got the definitions of various subroutines and the call to foo().
    For some reason, the defined check isn't catching that the functions are supposed to be defined elsewhere. Why is that?

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      G'day dragonchild,

      What your code is doing is calling the subroutine "$package::$funcName", and checking if it returns a defined value. This is certainly not what you want to be doing, because if the subroutine does not exist, you end up with a fatal errror.

      If your subroutine does exist, you've just invoked it with no arguments, and it could return undef just to spite you anyway.

      Rather than calling the subroutine, you instead want to use globs to access perl's symbol table. This is described in my reply above. It also happens to be a bit faster than methods using can(), since inheritance is not checked.

      Cheers,
      Paul