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

Hi all -

I'm wrestling with a little problem whose solution seems close at hand but remains elusive. I'd like to be able to use different modules depending on runtime conditions.

The modules that I would like to swap between export many functions, and in general, these functions have typically been called like someFunction. NB: someFunction is not passed null as in someFunction();

perlsub was enlightening but didn't quite answer this question.

use ModuleA; function_from_ModuleA; # This works.... function_from_ModuleA(); # and so does this... # Ah, but here's the rub... eval "use $desired_module"; ... function_from_desired_module; # nope. bareword. function_from_desired_module(); # works!
Might someone be able to explain this to me? Thanks in advance for your wisdom.

Replies are listed 'Best First'.
Re: eval use, exported functions, barewords
by liz (Monsignor) on Nov 07, 2003 at 18:48 UTC
    Before executing your program, Perl needs to compile your source. This happens at "compile time". This basically means that Perl goes through your source code and creates an internal, executable version of your program.

    At compile time, no execution takes place except when it encounters a use (or a BEGIN section, but that's not important right now).

    When Perl encounters a use, it basically does a require of that module at compile time and executes the "import" subroutine of the module after it has been loaded.

    The "import" subroutine of the module that you loaded, usually exports subroutines to your namespace. So, after the use, Perl "knows" that there is a subroutine called "function_from_ModuleA" because of the actions of the "import" subroutine.

    So, when Perl continues compiling your program and it encounters a bare word "function_from_ModuleA", it "knows" it is a subroutine and creates the associated internal representation for a subroutine call (without parameters).

    Another way that Perl knows at compile time whether a bareword is intended as a subroutine call, is when you prefix it with '&', or if you put a pair of parentheses after it.

    So, in your second case, the module has not been loaded yet and so Perl doesn't know what to do with the bareword. You have to provide a hint to Perl that you intend it to be a subroutine call.

    Apart from prefixing with '&" or suffixing '()', you can also tell Perl at compile time that there is going to be a subroutien "foo":

    sub foo; # note no body specified!

    Hope this helps.

    Liz

Re: eval use, exported functions, barewords
by perrin (Chancellor) on Nov 07, 2003 at 18:46 UTC
    As broquaint says, you have to declare your subs before using them as barewords. One way to do that is with the "subs" pragma:

    use subs qw(function_from_desired_module);
Re: eval use, exported functions, barewords
by broquaint (Abbot) on Nov 07, 2003 at 18:40 UTC
    To use bareword sub calls the subroutines musted be declared compiled before the bareword is seen so perl knows what to do with it. But since foo; and foo() are functionally equivalent it shouldn't really be an issue.
    HTH

    _________
    broquaint

    update: clarified explanation, thanks to diotalevi

      musted be compiled
      No, it must be declared first. Compilation can happen later.

      sub foo; # declaration foo; # call the function sub foo { ... } # definition
Re: eval use, exported functions, barewords
by simonm (Vicar) on Nov 07, 2003 at 18:50 UTC
    You need the module to be imported before the rest of the file is parsed, so you need to use a BEGIN block. (A normal use, without the eval, implicitly creates its own BEGIN block.)
    BEGIN { $desired_module = ... eval "use $desired_module"; } ... function_from_desired_module; # should be OK now.