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

I've read threads 19327 and 272402 that explain that expanding @INC within the code must be done in a BEGIN block. However I want to run some simple menus where the user selects one of multiple release directories (each with a plethora of scripts and modules for that release) and loads just one. Basically saying:
# a menu or two where the user makes a selections that lead up to defi +ning $lib and $module unshift(@INC, $lib); # done mid-execution, after the menu routines require "$module.pm"; # one clean import that loads a number of oth +ers all relative to $lib MODULE::main(@args); # execute a sub within the one of the newly i +mported modules within the selected lib
Is there any way to add a directory to the @INC path using a $variable and done after the BEGIN block? The only thing I can think of is a messy script-that-calls-a-script method that calls the menu routines first, then a second program with $lib and $module passed as args or some other fashion where they can be properly recognized in the BEGIN block.

Replies are listed 'Best First'.
Re: dynamically expand @INC beyond BEGIN
by JavaFan (Canon) on Apr 16, 2012 at 22:41 UTC
    One can modify @INC any time one pleases. Whether it's in a BEGIN block, or outside of it. However, for perl to find a module, the directory the module is to be found in should be added before perl goes looking for it. Considering that use is done at compile time, using a BEGIN (one which preceeds the use) is a simple way of enforcing @INC to be set in time.

    Using require and postponing the use of a module to run time, obviously works as well.

    Doesn't the snippet you gave work?

      feeling stupid at the moment.

      All morning it was continually saying cannot find MODULE.pm in <@INC_DIRS>, with the front dir being the one loaded that has the module in it. I couldn't figure why it would work when defined in the BEGIN block, but not in my code body and thought it had to be something to do with perl/@INC. Tried it one more time in the body and now it's working just fine. No idea what I had wrong there previously.

      Thanks for your help.

        Note that require "$lib/Module.pm" would also have worked if $lib contains an absolute directory (and probably even if it doesn't?)

        You could also make the change to @INC temporary using local @INC = ( $lib, @INC );.

Re: dynamically expand @INC beyond BEGIN
by Anonymous Monk on Apr 17, 2012 at 13:27 UTC
    Also, can you not use use lib?
      both $lib and $module are variables. use does not work with $vars in any way afaik.
        # Here's a variable... my $lib; # Make sure it gets defined at compile-time... BEGIN { $lib = '/foo' } # Use the variable in a "use" line... use lib $lib; # Check that it worked... use Data::Dumper; print Dumper \@INC;

        ... And lo and behold, it has worked!

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'