Perl的@INC是如何构造的? (又有什么方法可以影响搜索Perl模块的位置?) [英] How is Perl's @INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)

查看:102
本文介绍了Perl的@INC是如何构造的? (又有什么方法可以影响搜索Perl模块的位置?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以影响搜索Perl模块的位置? 或者, Perl的@INC是如何构建的?

What are all the ways of affecting where Perl modules are searched for? or, How is Perl's @INC constructed?

我们知道,

As we know, Perl uses @INC array containing directory names to determine where to search for Perl module files.

在StackOverflow上似乎没有完整的"@INC"常见问题解答类型的文章,因此,本问题仅供参考.

There does not seem to be a comprehensive "@INC" FAQ-type post on StackOverflow, so this question is intended as one.

推荐答案

我们将研究如何构造此数组的内容,并对其进行操作以影响Perl解释器在哪里找到模块文件.

We will look at how the contents of this array are constructed and can be manipulated to affect where the Perl interpreter will find the module files.

  1. 默认@INC

Perl解释器是编译的,具有特定的@INC默认值.要找出该值,请运行env -i perl -V命令(env -i忽略PERL5LIB环境变量-参见#2),然后在输出中将看到类似以下内容的内容:

Perl interpreter is compiled with a specific @INC default value. To find out this value, run env -i perl -V command (env -i ignores the PERL5LIB environmental variable - see #2) and in the output you will see something like this:

$ env -i perl -V
...
@INC:
 /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
 /usr/lib/perl5/site_perl/5.18.0
 /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
 /usr/lib/perl5/5.18.0
 .

最后请注意.;这是当前目录(不必与脚本目录相同).在Perl 5.26及更高版本中以及Perl与 -T一起运行时,缺少该属性(启用了污点检查).

Note . at the end; this is the current directory (which is not necessarily the same as the script's directory). It is missing in Perl 5.26+, and when Perl runs with -T (taint checks enabled).

要在配置Perl二进制编译时更改默认路径,请设置配置选项 otherlibdirs :

To change the default path when configuring Perl binary compilation, set the configuration option otherlibdirs:

Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3

  1. 环境变量PERL5LIB(或PERLLIB)

Perl在@INC前面加上外壳的PERL5LIB(如果未定义,则使用PERLLIB)中包含的目录列表(以冒号分隔).要在PERL5LIBPERLLIB环境变量生效后查看@INC的内容,请运行perl -V.

Perl pre-pends @INC with a list of directories (colon-separated) contained in PERL5LIB (if it is not defined, PERLLIB is used) environment variable of your shell. To see the contents of @INC after PERL5LIB and PERLLIB environment variables have taken effect, run perl -V.

$ perl -V
...
%ENV:
  PERL5LIB="/home/myuser/test"
@INC:
 /home/myuser/test
 /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
 /usr/lib/perl5/site_perl/5.18.0
 /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
 /usr/lib/perl5/5.18.0
 .

  • -I命令行选项

  • -I command-line option

    Perl用-I命令行选项的值传递的目录列表(用冒号分隔)预先附加在@INC之前.与Perl选项一样,可以通过三种方式完成此操作:

    Perl pre-pends @INC with a list of directories (colon-separated) passed as value of the -I command-line option. This can be done in three ways, as usual with Perl options:

    • 在命令行中传递它:

    • Pass it on command line:

    perl -I /my/moduledir your_script.pl
    

  • 通过Perl脚本的第一行(shebang)传递它:

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

    #!/usr/local/bin/perl -w -I /my/moduledir
    

  • 将其作为PERL5OPT(或PERLOPT)环境变量的一部分传递(请参见编程Perl )

  • Pass it as part of PERL5OPT (or PERLOPT) environment variable (see chapter 19.02 in Programming Perl)

    通过 lib编译指示

    Pass it via the lib pragma

    Perl在@INC前面加上了通过use lib传入的目录列表.

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

    在程序中:

    use lib ("/dir1", "/dir2");
    

    在命令行上:

    perl -Mlib=/dir1,/dir2
    

    您还可以通过@INC中删除目录> .

    You can also remove the directories from @INC via no lib.

    您可以直接将@INC作为常规Perl数组进行操作.

    You can directly manipulate @INC as a regular Perl array.

    注意:由于在编译阶段使用了@INC,因此必须在use MyModule语句之前的BEGIN {}块内部完成.

    Note: Since @INC is used during the compilation phase, this must be done inside of a BEGIN {} block, which precedes the use MyModule statement.

    • 通过unshift @INC, $dir将目录添加到开头.

    通过push @INC, $dir将目录添加到末尾.

    Add directories to the end via push @INC, $dir.

    使用Perl数组可以做其他任何事情.

    Do anything else you can do with a Perl array.

    注意:目录按此答案中列出的顺序未移位@INC上,例如默认的@INC在列表的最后,在PERL5LIB之后,在-I之后,在use lib和直接@INC操作之前,后两者以Perl代码中的顺序混合.

    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.

    • 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?

    关于Stack Overflow似乎没有一个全面的@INC常见问题解答类型的帖子,因此该问题仅供参考.

    There does not seem to be a comprehensive @INC FAQ-type post on Stack Overflow, so this question is intended as one.

    • 如果目录中的模块需要由站点上的许多脚本/所有脚本使用,尤其是由多个用户运行,则该目录应包含在编译为Perl二进制文件的默认@INC中.

    如果该目录中的模块将由特定用户专用于该用户运行的所有脚本(或者在以前的用例中,如果重新编译Perl不是更改默认@INC的选项),请设置用户的PERL5LIB,通常是在用户登录期间.

    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.

    注意:请注意通常的Unix环境变量陷阱-例如在某些情况下,以特定用户身份运行脚本并不能保证在该用户的环境设置下运行脚本,例如通过su.

    如果仅在特定情况下(例如,在开发/调试模式下执行脚本时)需要使用目录中的模块,则可以手动设置PERL5LIB或通过 perl选项.

    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 pass the -I option to perl.

    如果仅需要将模块用于特定脚本,则使用它们的所有用户都应在程序本身中使用use lib/no lib编译指示.当需要在运行时动态确定要搜索的目录时也应使用它-例如通过脚本的命令行参数或脚本的路径(有关非常好的用例,请参见 FindBin 模块).

    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 the script's command line parameters or script's path (see the FindBin module for very nice use case).

    如果需要根据某些复杂的逻辑来操作@INC中的目录,那么通过结合使用use lib/no lib编译指示来实现它是不可能的,以至于太笨拙了,那么请在内部使用直接的@INC操作BEGIN {}块或在为@INC操作指定的专用库中,必须在使用其他任何模块之前由脚本使用这些.

    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.

    一个例子是自动在prod/uat/dev目录中的库之间切换,如果dev和/或UAT中缺少瀑布库拾取,则在prod中使用瀑布库拾取(最后一个条件使得标准的"use lib + FindBin"解决方案相当复杂. 如何使用Beta Perl脚本中的Beta Perl模块? .

    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 How do I use beta Perl modules from beta Perl scripts?.

    直接操作@INC的另一个用例是能够添加子例程引用或对象引用(是的,弗吉尼亚州,@INC可以包含自定义Perl代码,而不仅仅是目录名称,如<一个href ="https://stackoverflow.com/questions/2541119/when-is-a-subroutine-reference-in-inc-inc">> 何时在@INC中调用一个子例程引用? ).

    An additional use case for directly manipulating @INC is to be able to add subroutine references or object references (yes, Virginia, @INC can contain custom Perl code and not just directory names, as explained in When is a subroutine reference in @INC called?).

    这篇关于Perl的@INC是如何构造的? (又有什么方法可以影响搜索Perl模块的位置?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆