web-dev-qa-db-ja.com

Perlの@INCはどのように構築されますか? (別名Perlモジュールが検索される場所に影響を与えるすべての方法は何ですか?)

Perlモジュールの検索場所に影響を与えるすべての方法は何ですか?または、Perlの@INCはどのように構築されますか

Perlはディレクトリ名を含む@INC配列を使用して、Perlモジュールファイルの検索場所を決定します

StackOverflowに関する包括的な「@INC」FAQタイプの投稿はないようですので、この質問は1つとして意図されています。

197
DVK

この配列の内容がどのように構成され、Perlインタープリターがモジュールファイルを検索する場所に影響するように操作できるかを見ていきます。

  1. デフォルト@INC

    Perlインタープリターは 特定の@INCデフォルト値でコンパイル です。この値を確認するには、env -i Perl -Vコマンドを実行します(env -iPerl5LIB環境変数を無視します-#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 5.26以降では欠落しており、Perlが -T(汚染チェックが有効) で実行されている場合は欠落しています。

Perlバイナリコンパイルの設定時にデフォルトパスを変更するには、設定オプション otherlibdirs を設定します。

Configure -Dotherlibdirs=/usr/lib/Perl5/site_Perl/5.16.3

  1. 環境変数Perl5LIB(またはPERLLIB

    Perlは、シェルの環境変数@INC(定義されていない場合はPERLLIBが使用されます)に含まれるディレクトリのリスト(コロン区切り)をPerl5LIBに事前に付加します。 @INCおよびPERLLIB環境変数が有効になった後のPerl5LIBの内容を表示するには、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オプションを使用した通常の3つの方法で実行できます。

    • コマンドラインで渡します:

      Perl -I /my/moduledir your_script.pl
      
    • Perlスクリプトの最初の行(Shebang)を介して渡します。

      #!/usr/local/bin/Perl -w -I /my/moduledir
      
    • Perl5OPT(またはPERLOPT)環境変数の一部として渡します( Programming Perl の19.02章を参照)

  3. libプラグマ で渡します

    Perlは、@INCを介して渡されたディレクトリのリストをuse libに事前に追加します。

    プログラム内:

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

    コマンドラインで:

    Perl -Mlib=/dir1,/dir2
    

    @INCからno libからディレクトリを削除 することもできます。

  4. @INCを通常のPerl配列として直接操作できます。

    注:@INCはコンパイル段階で使用されるため、これはBEGIN {}ステートメントの前にあるuse MyModuleブロック内で実行する必要があります。

    • unshift @INC, $dirを使用して先頭にディレクトリを追加します。

    • Push @INC, $dirを介して最後にディレクトリを追加します。

    • Perl配列でできることは何でもします。

注:ディレクトリは、この回答にリストされている順序で@INCunshiftedされます。デフォルトの@INCは、リストの最後にあり、Perl5LIBが前にあり、-Iが前にあり、use libが前にあり、@INCが直接操作されます。

参照:

Stack Overflowに関する包括的な@INC FAQタイプの投稿はないようです。そのため、この質問は1つの質問です。

各アプローチを使用するタイミング

  • ディレクトリ内のモジュールをサイト上の多く/すべてのスクリプトで使用する必要がある場合、特に複数のユーザーが実行する必要がある場合、そのディレクトリはPerlバイナリにコンパイルされたデフォルトの@INCに含める必要があります。

  • ディレクトリ内のモジュールが、ユーザーが実行するすべてのスクリプトに対して特定のユーザーによって排他的に使用される場合(またはPerlの再コンパイルが以前のユースケースでデフォルトの@INCを変更するオプションではない場合)、通常はユーザーのログイン中にユーザーのPerl5LIBを設定します。

    注:通常のUnix環境変数の落とし穴に注意してください-例:特定の場合、特定のユーザーとしてスクリプトを実行しても、そのユーザーの環境がセットアップされた状態でスクリプトを実行することは保証されません。 su経由

  • ディレクトリ内のモジュールを特定の状況でのみ使用する必要がある場合(たとえば、スクリプトを開発/デバッグモードで実行する場合)、Perl5LIBを手動で設定するか、-IオプションをPerlに渡すことができます。

  • モジュールを使用するallユーザーが特定のスクリプトのみにモジュールを使用する必要がある場合は、プログラム自体でuse lib/no libプラグマを使用します。また、実行中に検索するディレクトリを動的に決定する必要がある場合にも使用する必要があります。スクリプトのコマンドラインパラメーターまたはスクリプトのパスから(非常に素晴らしい使用例については FindBin モジュールを参照してください)。

  • @INCのディレクトリをいくつかの複雑なロジックに従って操作する必要がある場合、use lib/no libプラグマを組み合わせて実装するには扱いにくいため、@INCブロック内またはBEGIN {}操作用に指定された特別な目的のライブラリ内で直接@INC操作を使用します他のモジュールを使用する前に、スクリプトで使用する必要があります。

    この例は、prod/uat/devディレクトリのライブラリを自動的に切り替えることです。devおよび/またはUATから欠落している場合、prodでウォーターフォールライブラリをピックアップします(最後の条件により、標準の "use lib + FindBin"ソリューションがかなり複雑になります。このシナリオの詳細なイラストは ベータPerlスクリプトからベータPerlモジュールを使用するにはどうすればよいですか?

  • @INCを直接操作するための追加の使用例は、サブルーチン参照またはオブジェクト参照を追加できることです(はい、バージニア州、@INCで説明されているように、ディレクトリ名だけでなくカスタムPerlコードを含むことができます@INCのサブルーチン参照はいつ呼び出されますか? )。

251
DVK

上記の場所に加えて、OS XバージョンのPerlにはさらに2つの方法があります。

  1. /Library/Perl/x.xx/AppendToPathファイル。このファイルにリストされているパスは、実行時に@INCに追加されます。

  2. /Library/Perl/x.xx/PrependToPathファイル。このファイルにリストされているパスは、実行時に@INCの前に追加されます。

17
dgatwood

すでに述べたように、@ 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によってエクスポートされます。

6
Kacper Perschke