Reputation: 1482
I have a Perl script that is using two modules. The first module also uses the second module.
If the first module does use lib 'dir1'
, and the script does use lib 'dir2'
:
module1.pm
use lib "dir1";
use module2;
script.pl
use lib "dir2";
use module1;
use module2;
which directory is being used by the first module? Does the script's use lib, 'dir2'
override the use lib, 'dir1'
in the first module, or do they have different scope?
I did my own testing, and printed the @INC inside module1.pm and script.pl, the result was the dir1 was at the top of @INC.
Upvotes: 1
Views: 9006
Reputation: 35198
You obviously know that lib
works on the @INC
array. However, you appear to be thinking of it as an array of a single value that is replaced by subsequent usage.
Borodin's already explained the mechanisms well, and the docs for lib
do an even better job. However, perhaps a little example script will help:
use strict;
use warnings;
use Data::Dump qw(dump);
# Set @INC to minimum required for lib
BEGIN {
require lib;
@INC = $INC{'lib.pm'} =~ s/lib.pm//r;
print "\@INC = " . dump(@INC) . "\n\n";
}
# Try adding two directories
use lib 'foo';
BEGIN {
print "use lib 'foo';\n";
print "# \@INC is " . dump(@INC) . "\n\n";
}
use lib 'bar';
BEGIN {
print "use lib 'bar';\n";
print "# \@INC is " . dump(@INC) . "\n\n";
}
# Remove a directory
no lib 'foo';
BEGIN {
print "no lib 'foo';\n";
print "# \@INC is " . dump(@INC) . "\n";
}
Outputs:
@INC = "C:/strawberry/perl/lib/"
use lib 'foo';
# @INC is ("foo", "C:/strawberry/perl/lib/")
use lib 'bar';
# @INC is ("bar", "foo", "C:/strawberry/perl/lib/")
no lib 'foo';
# @INC is ("bar", "C:/strawberry/perl/lib/")
Upvotes: 2
Reputation: 126722
The lib
pragma just does an unshift
of the path onto the global (and package-independent) array @INC
. Nothing is ever removed from @INC
unless it is done explicitly.
The first time it is encountered is on the first line of the script.pl
, so thereafter @INC
will contain dir2
.
The next thing that happens is that script.pl
compiles and runs module1.pm
. (It will look for it in dir2
first, and then in the directories that were originally in @INC
.) The first line of that file contains another use lib
, which will unshift @INC, 'dir1'
.
Thereafter @INC
stays the same. Any further use
or require
will look in dir1
first (because it was shifted last) then dir2
, and then in the rest of @INC
.
Upvotes: 3
Reputation: 1560
See the perl doc on use lib
: http://perldoc.perl.org/lib.html
When script.pl runs, it will prepend "dir2" to @INC
. It will then look for module1 in the directories listed in @INC
starting with "dir2".
When it is loading module1, it will prepend "dir1" to @INC
and then look for and load module2 in the directories now listed in @INC
, which starts with dir1, then dir2 and then the remaining directories in @INC
. Once it has loaded module2, it will finish loading module1.
The use module2
line in script.pl will be ignored at this point.
Upvotes: 1