Perl的@INC是如何构造的? (又名影响 Perl 模块搜索位置的所有方法是什么?)

2024-02-14

影响 Perl 模块搜索位置的方式有哪些? 或者,Perl的@INC是如何构造的?

据我们所知,Perl 使用@INC包含目录名称的数组,用于确定在哪里搜索 Perl 模块文件 https://stackoverflow.com/questions/2526520/how-does-a-perl-program-know-where-to-find-the-file-containing-perl-module-it-use.

StackOverflow 上似乎没有全面的“@INC”常见问题解答类型帖子,因此此问题旨在作为一个问题。


我们将了解如何构造该数组的内容,并对其进行操作以影响 Perl 解释器在何处找到模块文件。

  1. Default @INC

    Perl 解释器是用特定的编译@INC默认值 http://search.cpan.org/perldoc/INSTALL。要找出该值,请运行env -i perl -V命令 (env -i忽略PERL5LIB环境变量 - 请参阅#2),在输出中您将看到如下内容:

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

Note .在最后;这是当前目录(不一定与脚本的目录相同)。它在 Perl 5.26+ 中缺失,当 Perl 运行时-T(已启用污点检查) http://perldoc.perl.org/perlrun.html#*-T*.

要更改配置 Perl 二进制编译时的默认路径,请设置配置选项otherlibdirs http://search.cpan.org/perldoc?INSTALL#otherlibdirs:

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

  1. 环境变量PERL5LIB (or PERLLIB)

    Perl 前置@INC包含目录列表(以冒号分隔)PERL5LIB(如果没有定义,PERLLIB使用)shell 的环境变量。要查看的内容@INC after PERL5LIB and PERLLIB环境变量已经生效,运行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
     .
    
  2. -I命令行选项

    Perl 前置@INC目录列表(以冒号分隔)作为值传递-I命令行选项。这可以通过三种方式完成,就像通常使用 Perl 选项一样:

    • 在命令行上传递它:

      perl -I /my/moduledir your_script.pl
      
    • 通过 Perl 脚本的第一行 (shebang) 传递它:

      #!/usr/local/bin/perl -w -I /my/moduledir
      
    • 将其作为一部分传递PERL5OPT (or PERLOPT) 环境变量(参见第 19.02 章Perl编程 http://oreilly.com/catalog/9780596004927)

  3. 通过它传递lib pragma http://perldoc.perl.org/lib.html

    Perl 前置@INC通过传递给它的目录列表use lib.

    在一个程序中:

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

    在命令行上:

    perl -Mlib=/dir1,/dir2
    

    你也可以从中删除目录@INC via no lib http://perldoc.perl.org/lib.html#Deleting-directories-from-@INC.

  4. 可以直接操作@INC作为常规 Perl 数组。

    注:自@INC在编译阶段使用,这必须在一个内部完成BEGIN {}块,位于use MyModule陈述。

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

    • 通过以下方式将目录添加到末尾push @INC, $dir.

    • 做任何你能用 Perl 数组做的事情。

注意:目录是不变的 onto @INC按照此答案中列出的顺序,例如默认@INC是列表中的最后一个,前面是PERL5LIB,前面是-I,前面是use lib并直接@INC操作,后两者按照它们在 Perl 代码中的顺序混合。

参考:

  • perldoc perlmod http://perldoc.perl.org/perlmod.html#Perl-Modules
  • perldoc 库 http://perldoc.perl.org/lib.html
  • Perl 模块机制 - 包含实用操作方法的优秀指南 http://world.std.com/~swmcd/steven/perl/module_mechanics.html
  • 如何在目录中“使用”Perl 模块而不是在目录中@INC? https://stackoverflow.com/questions/185114/how-do-i-use-a-perl-module-in-a-directory-not-in-inc
  • Perl编程 https://rads.stackoverflow.com/amzn/click/com/0596000278- 第 31 章第 13 部分,第 7.2.41 章
  • Perl 程序如何知道在哪里可以找到包含它使用的 Perl 模块的文件? https://stackoverflow.com/questions/2526520/how-does-a-perl-program-know-where-to-find-the-file-containing-perl-module-it-use

好像没有一个全面的@INCStack Overflow 上的常见问题解答类型帖子,因此本问题旨在作为一个问题。

何时使用每种方法?

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

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

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

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

  • 如果模块仅需要用于特定脚本,则通过all使用它们的用户,使用use lib/no lib程序本身的编译指示。当需要在运行时动态确定要搜索的目录时,也应该使用它 - 例如从脚本的命令行参数或脚本的路径(请参阅FindBin http://p3rl.org/FindBin模块非常好的用例)。

  • 如果目录在@INC需要根据一些复杂的逻辑进行操作,要么不可能,要么太笨拙,无法通过组合来实现use lib/no lib编译指示,然后直接使用@INC内部操纵BEGIN {}块或指定用于的特殊用途库内@INC操作,您的脚本必须在使用任何其他模块之前使用它。

    一个例子是在 prod/uat/dev 目录中的库之间自动切换,如果 dev 和/或 UAT 中缺少瀑布库,则在 prod 中拾取瀑布库(最后一个条件使标准“使用 lib + FindBin”解决方案相当复杂。 此场景的详细说明位于如何使用 beta Perl 脚本中的 beta Perl 模块? https://stackoverflow.com/questions/2474588/how-do-i-use-beta-perl-modules-from-beta-perl-scripts.

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Perl的@INC是如何构造的? (又名影响 Perl 模块搜索位置的所有方法是什么?) 的相关文章

随机推荐