Resove the problem of @INC of perl.

  1. 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:

  2. $ 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 
    

  3. -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:

    • Pass it on command line: perl -I /my/moduledir your_script.pl

    • Pass it via the first (shebang) line of your Perl script:

    #!/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)
  4. Pass it via the use lib pragma

    Perl pre-pends @INC with a list of directories passed in to it via use lib pragma.

  1. 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

  2. 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.

  1. 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

  2. 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, 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.

References:

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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值