5

Let's say there are three paths in @INC: path1, path2 and path3. Under each of these paths, there is a module named foo.pm. If I now load foo.pm in my script via use foo;, which of the foo.pms is actually going to be loaded? Or in other words, what is perl's search order for paths in @INC?

zb226
  • 9,586
  • 6
  • 49
  • 79
Haiyuan Zhang
  • 40,802
  • 41
  • 107
  • 134
  • 1
    possible duplicate of [How do I choose a package name for a custom Perl module that does not collide with builtin or CPAN packages names?](http://stackoverflow.com/questions/658955/how-do-i-choose-a-package-name-for-a-custom-perl-module-that-does-not-collide-wi) (That question covers more ground, but it includes this question.) – cjm Dec 02 '11 at 16:57
  • possible duplicate of [How does a Perl program know where to find the file containing Perl module it uses?](http://stackoverflow.com/questions/2526520/how-does-a-perl-program-know-where-to-find-the-file-containing-perl-module-it-us) . Also see http://stackoverflow.com/questions/2526804/how-is-perls-inc-constructed-aka-what-are-all-the-ways-of-affecting-where-pe – DVK Dec 03 '11 at 09:02

2 Answers2

8

perldoc -v %INC shows which path was chosen:

use Data::Dumper; 
print Dumper(\%INC);

Or...

perl -Mfoo -e 'print $INC{"foo.pm"}'

require shows some psuedo-code which implies the search order:

foreach $prefix (@INC) {
}

Thus, path1 would be searched first.

daxim
  • 39,270
  • 4
  • 65
  • 132
toolic
  • 57,801
  • 17
  • 75
  • 117
6

path1, path2, path3. And perl will load path1/foo.pm.

Why would you expect it to be any other?

Looking at perlfunc perlvar, I can see that they don't explicitly say this, but they do say:

The array @INC contains the list of places that the do EXPR , require, or use constructs look for their library files.

I think the hint on there is list. It's unexceptional to expect a list to be processed first-to-last.

You could probably put this code, right before your use foo; statement:

BEGIN { say "\@INC=(${\join( ', ', @INC )})"; }

If that still shows you @INC=(/path1, /path2, /path3) then put this after the use statement:

BEGIN { say "\$INC{'foo.pm'}=$INC{'foo.pm'}"; }

And if that one still shows $INC{'foo.pm'}=/path3/foo.pm, then I think you're not specifying your search paths as well as you might. You might think you have foo.pm in the same directory specified as '/path1', but the likelihood is that you've got some path messed up.

Axeman
  • 29,660
  • 2
  • 47
  • 102
  • \@Axeman: I print @INC and the printed order is path1, path2 and path3, me too expected that it's path1/foo.pm is loaded, but in my case path3/foo.pm is loaded. there are two possibilities here, one is that the printed order is the reverse of search order, or something crazy... – Haiyuan Zhang Dec 02 '11 at 14:18
  • 1
    @HaiyuanZhang `@INC` should print out in order, again as it is a list. Perhaps you do some manipulation with `@INC` in something that runs after the `BEGIN` blocks (and remember that `use` is an implicit `BEGIN` block). So you can write code like this: `unshift @INC, qw;use foo;` and end up with an implementation of `foo` in the path3. Sequential location in the file does not dictate sequential processing, necessarily. See [`use`](http://perldoc.perl.org/functions/use.html) – Axeman Dec 02 '11 at 14:24