perl-module use用法 - Perl的@INC是如何構建的? (又名什麼是影響Perl模塊搜索的方式?)




perl安裝 modules (4)

據說已經@INC是一個數組,你可以自由地添加任何你想要的。

我的CGI REST腳本如下所示:

#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
    push @INC, 'fully_qualified_path_to_module_wiht_our_REST.pm';
}
use Modules::Rest;
gone(@_);

子程序消失由Rest.pm導出。

影響Perl模塊搜索的所有方法是什麼? 或者, Perl的@INC是如何構建的

我們知道, Perl使用包含目錄名稱的@INC數組來確定在哪裡搜索Perl模塊文件

在中似乎沒有全面的“@INC”常見問題解答類型帖子,所以這個問題只能作為一個。


我們將看看這個數組的內容是如何構造的,並且可以被操縱來影響Perl解釋器將在哪裡找到模塊文件。

  1. 默認@INC

    Perl解釋器是用特定的@INC默認值編譯的 。 要找出這個值,運行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
     .
    

    注意. 最後; 這是當前目錄。 Perl運行時使用-T (啟用了污點檢查)時缺失。

    要在配置Perl二進制編譯時更改默認路徑,請設置配置選項otherlibdirs

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

  2. 環境變量PERL5LIB (或PERLLIB

    Perl預先將@INC與包含在您的shell的PERL5LIB (如果未定義,使用PERLLIB )環境變量中的目錄列表(以冒號分隔) PERL5LIB 。 在PERL5LIBPERLLIB環境變量生效後,要查看@INC的內容,請運行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
     .
    
  3. -I命令行選項

    Perl預先將@INC與作為-I命令行選項的值傳遞的目錄列表(以冒號分隔)進行傳遞。 這可以通過三種方式完成,像往常一樣使用Perl選項:

    • 通過命令行傳遞它:

      perl -I /my/moduledir your_script.pl
      
    • 通過Perl腳本的第一行(shebang)傳遞它:

      #!/usr/local/bin/perl -w -I /my/moduledir
      
    • 將它作為PERL5OPT (或PERLOPT )環境變量的一部分傳遞(請參閱Programming Perl中的第19.02章)

  4. 通過lib雜注傳遞它

    Perl預先將@INC與通過use lib的目錄列表相關聯。

    在一個程序中:

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

    在命令行上:

    perl -Mlib=/dir1,/dir2
    

    您也可以通過no lib@INC刪除這些目錄

  5. 你可以直接操作@INC作為普通的Perl數組。

    注意:由於在編譯階段使用了@INC ,因此必須在use MyModule語句之前的BEGIN {}塊內完成。

    • 通過unshift @INC, $dir將目錄添加到開頭。

    • 通過push @INC, $dir將目錄添加到最後。

    • 做任何你可以用Perl數組做的事情。

注意:這個目錄在這個答案中列出的順序是不移動@INC上的,例如默認@INC是列表中的最後一個,前面是PERL5LIB ,前面是-I ,前面是use lib和直接@INC操作,後面兩個混合無論他們在Perl代碼中的順序。

參考文獻:

似乎沒有全面的@INC FAQ-type文章,所以這個問題只能作為一個。

何時使用每種方法?

  • 如果目錄中的模塊需要被站點上的許多/所有腳本使用,特別是由多個用戶運行,則該目錄應該包含在編譯到Perl二進製文件中的默認@INC

  • 如果目錄中的模塊將由特定用戶專門用於所有用戶運行的腳本(或者在以前的用例中重新編譯Perl不是更改默認@INC的選項),請設置用戶的PERL5LIB ,通常在用戶登錄。

    注意:請注意通常的Unix環境變量缺陷 - 例如在某些情況下運行腳本,因為特定用戶不能保證在設置了該用戶環境的情況下運行它們,例如通過su

  • 如果目錄中的模塊只能在特定情況下使用(例如腳本以開發/調試模式執行),則可以手動設置PERL5LIB ,或將-I選項傳遞給perl。

  • 如果模塊僅用於特定腳本, 所有使用它們的用戶都可以在程序中use lib / no lib編譯指示。 當運行時需要動態確定要搜索的目錄時(例如,從腳本的命令行參數或腳本路徑(請參閱FindBin模塊以獲得非常好的用例)),也應該使用它。

  • 如果@INC的目錄需要根據一些複雜的邏輯進行操作,要么通過結合use lib / no lib編譯指示來實現,要么不太複雜,然後在BEGIN {}塊中或在專用目錄庫中使用直接的@INC操作指定用於@INC操作,在使用任何其他模塊之前,腳本必須使用它們。

    例如,prod / uat / dev目錄中的庫自動切換,如果從dev和/或UAT中缺少瀑布庫,prod中的瀑布庫將會自動切換(最後一個條件使標準“使用lib + FindBin”解決方案非常複雜。這個場景的詳細說明在於如何使用beta Perl腳本中的beta Perl模塊?

  • 直接操作@INC的另一個用例是能夠添加子例程引用或對象引用(是的,Virginia, @INC可以包含自定義Perl代碼,而不僅僅是目錄名稱,如@INC中的子例程引用時所述? )。


除了上面列出的位置之外,OS X版本的Perl還有兩種方法:

  1. /Library/Perl/x.xx/AppendToPath文件。 此文件中列出的路徑在運行時會附加到@INC。

  2. /Library/Perl/x.xx/PrependToPath文件。 在此文件中列出的路徑在運行時被預置為@INC。


你可以使用:

my ($arg1, $arg2) = @_;

要明確限制可以使用的參數數量:

my $number =2;
die "Too many arguments" if @_ > $number;




perl perl-module