Reputation: 696
How do I load a module with a path not in the @INC in Perl?
I've read the answers on how to add a path to the @INC, but the issue is that @INC has to be changed at the beginning of the code. After it's compiled, all the modules I've come across look to @INC to find the location of the module. My issue is that we're trying to separate out all these environment specific things to a config file. If it's in a config file, the path needs to be read before it can be pushed to @INC, but then the code has already been compiled and it seems @INC can't be modified.
Upvotes: 3
Views: 1096
Reputation: 696
Came across only, which seems to let a path be passed to the use
argument like so:
use only { versionlib => '/home/ingy/modules' },
MyModule => 0.33;
It has to be used with a version condition, but putting this here anyways since it's relevant to my question 1 and I wasn't able to find any modules first time around that allowed a path outside @INC.
require supposedly is able to take in a full path, according to the perlfaq with
require "$ENV{HOME}/lib/Foo.pm"; # no @INC searching!
Upvotes: 0
Reputation: 35198
Use a BEGIN
block to load your custom @INC
location and then use lib
to include it.
# use lib /a special directory/
BEGIN {
my $lib_to_include = ...;
require lib;
lib->import($lib_to_include);
}
use Module_That_Requires_Special_Dir;
The only thing to note is that whatever code you use to load your custom include directory will have to rely on methods already defined before this BEGIN
block. Therefore you can't use a subroutine that is later in the file.
Upvotes: 3
Reputation: 57600
Perl has an incremental compilation model which means that code can be executed before other code is even parsed. For this, we can use phase blocks (aka. phasers):
BEGIN {
print "This is executed as soon as the block has been parsed\n";
}
Such a phase block could also be used to load a configuration file.
For example, use
statements are effectively syntactic sugar for a BEGIN
block.
use Foo::Bar qw/baz qux/;
is equivalent to
BEGIN {
require Foo::Bar; # or: require "Foo/Bar.pm";
Foo::Bar->import(qw/baz qux/);
}
We can also load modules at runtime, although that's only sensible for object-oriented modules.
So we have three options:
BEGIN
phase and add the correct library paths before loading the actual modulesBEGIN
with their full path (e.g. require "/my/modules/Foo/Bar.pm"
Using bare require
is fairly uncomfortable, which is why Module::Runtime
exists
Upvotes: 9