-
Default @INC Perl interpreter is compiled with a specific default value of @INC that it was compiled with. To find out this value,run env -i perl -V command (`env -i ignores PERL5LIB environmental variable - see #2) and in the output you will see something like this:
-
$ perl -V ... %ENV: ? PERL5LIB="/home/myuser/test" @INC: ?/home/myuser/test ?/usr/local/lib/perl5/5.8.6/i686-linux ?/usr/local/lib/perl5/5.8.6 ?/usr/local/lib/perl5/site_perl/5.8.6/i686-linux ?/usr/local/lib/perl5/site_perl
-
-I command line parameter Perl pre-pends @INC with a list of directories (colon-separated) passed in to it as a value of -I command line parameter. This can be done in one of two ways,as usual with Perl parameters:
#!/usr/local/bin/perl -w -I /my/moduledir
- Pass it as part of
PERL5OPT (or PERLOPT ) environmantal variable (see chapter 19.02 in Programming Perl)
-
Pass it via the use lib pragma Perl pre-pends @INC with a list of directories passed in to it via use lib pragma.
-
In a program: use lib ("/dir1","/dir2") On the command line: perl -Mlib=/dir1,/dir2 You can also remove the directories from @INC via no lib
-
You can directly manipulate @INC as a regular Perl array. NOTE: Since @INC us used during compilation phase,this must be done inside of a BEGIN {} block,which precedes the use MyModule statement;
-
Add directories to the beginning via unshift @INC,$dir
-
Add directories to the end via push @INC,$dir
-
Do anything else you can do with a Perl array.
NOTE The directories are unshifted onto @INC in the order listed in this answer,e.g. default @INC is last in the list,preceded by PERL5LIB,preceded by -I,preceded by "use lib" and direct @INC manipulation,the latter two mixed in whichever order they are in Perl code.
40
down vote
accepted
|
We will look at how the contents of this array are constructed and can be manipulated to affect where Perl interpreter will find the module files.
-
Default @INC Perl interpreter is compiled with a specific default value of @INC that it was compiled with. To find out this value,run env -i perl -V command (`env -i ignores PERL5LIB environmental variable - see #2) and in the output you will see something like this:
$ env -i perl -V ... @INC: ?/usr/local/lib/perl5/5.8.6/i686-linux ?/usr/local/lib/perl5/5.8.6 ?/usr/local/lib/perl5/site_perl/5.8.6/i686-linux ?/usr/local/lib/perl5/site_perl
To change the default path when configuring Perl binary compilation,use otherlibdirs variable:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.8.1
-
Environmental variable PERL5LIB (or PERLLIB ) Perl pre-pends @INC with a list of directories (colon-separated) contained in PERL5LIB (if it is not defined,PERLLIB is used) environmental variable of your shell. To see the contents of @INC after PERL5LIB and PERLLIB environment variables have taken effect,run perl -V .
|
The directories are
unshifted onto @INC in the order listed in this answer,the latter two mixed in whichever order they are in Perl code.
References:
- perldoc perlmod
- perldoc lib
- Perl Module Mechanics - a great guide containing practical HOW-TOs
- How do I 'use' a Perl module in a directory not in
@INC ?
-
Programming Perl - chapter 31 part 13,ch 7.2.41
- How does a Perl program know where to find the file containing Perl module it uses?
There does not seem to be a comprehensive "@INC" FAQ-type post on StackOverflow,so this question is intended as one.
When to use each approach?
-
If the modules in a directory need to be used by many/all scripts on your site,especially run by multiple users,that directory should be included in default @INC compiled into Perl binary
-
If the modules in the directory will be used exclusively by a specific user for all the scripts that user runs (or if recompiling Perl is not an option to change default @INC in previous use case),set the users' PERL5LIB ,usually during user login. NOTE: Please be aware of the usual Unix environment variable pitfalls - e.g. in certain cases running the scripts as a particular user does not guarantee running them with that user's environment set up,e.g. via su .
-
If the modules in the directory need to be used only in specific circumstances (e.g. when the script(s) is executed in development/debug mode,you can either set PERL5LIB manually,or use "-I" perl parameter.
-
If the modules need to be used only for specific scripts,by ALL users using them,use use lib/no lib pragmas in the program itself. It also should be used when the directory to be searched needs to be dynamically determined during runtime - e.g. from script's command line parameters or script's path (see FindBin module for very nice use case)
-
If the directories in @INC need to be manipulated according to some complicated logic,either impossible to too unwieldy to implement by combination of "use lib/no lib" pragmas,then use direct @INC manipulation inside BEGIN {} block or inside a special purpose library designated for @INC manipulation,which must be used by your script(s) before any other modules are used. An example of this is automatically switching between libraries in prod/uat/dev directories,with waterfall library pickup in prod if it's missing from dev and/or UAT (the last condition makes the standard "use lib + FindBin" solution fairly complicated.A detailed illustration of this scenario is in this SO post.
-
An additional use case for directly manipulating @INC is to be able to add subroutine references or object references (yes,Virgina,@INC can contain custom Perl code and not just directory names,as explained here)
Original Link: http://stackoverflow.com/questions/2526804/how-is-perls-inc-constructed-aka-what-are-all-the-ways-of-affecting-where-pe
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|