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


199

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

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

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


7
ええ、でもsearch.cpan.org/perldoc/…に完全に良いものがありますか?
mob

3
@mobrule:完全に近いもの@INCではなく、実行時に追加する方法を伝えるだけの包括的なものではありません。
Cascabel

2
@mobrule - @Jefromiは、右推測-私がこれまでに発見されたとのすべての参照の主な問題は、perlのバイナリのコンパイル時にデフォルト@INCに関する包括的な情報の欠如だった
DVK

3
パッチを送って、その答えを包括的にする人もいます。perlfaqはGithubにあるので簡単です。:)
brian d foy

1
まあ、「perlバイナリのコンパイル済みデフォルト@INCに関する包括的な情報」は、それをコンパイルした人が設定したものだということです。そこにたどり着くさまざまな道について尋ねるなら、あなたが答えたものとは異なる質問があると思います。
ブライアン・ド・フォイ2010年

回答:


254

この配列の内容がどのように構築され、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 5.26以降では欠落しており、Perlが-T(汚染チェックが有効になっている)状態でます。

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

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

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

    Perl は、シェルの環境変数(定義されていない場合は使用されます@INC)に含まれているPERL5LIB(コロンで区切られた)ディレクトリのリストを先頭に付加しPERLLIBます。@INCafter PERL5LIBおよび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オプションの場合と同様に、3つの方法で実行できます。

    • コマンドラインで渡してください:

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

      #!/usr/local/bin/perl -w -I /my/moduledir
    • PERL5OPT(またはPERLOPT)環境変数の一部として渡します(Perlのプログラミングの 19.02章を参照)。

  3. プラグマを介して渡しますlib

    Perlプリペ​​ンド @INCは、を介して渡されたディレクトリのリストをしuse libます。

    プログラム内:

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

    コマンドラインで:

    perl -Mlib=/dir1,/dir2

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

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

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

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

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

    • Perl配列でできることは他に何でもしてください。

注:ディレクトリは、この回答にリストされている順序でシフト@INCません。たとえば、デフォルト@INCはリストの最後にあり、前にPERL5LIB、前に-I、前にuse libし、直接@INC操作があり、後者の2つは、Perlコード内の順序で混在しています。

参照:

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

それぞれのアプローチをいつ使用するのですか?

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

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

    注:通常のUnix環境変数の落とし穴に注意してください。たとえば、特定のユーザーとしてスクリプトを実行しても、そのユーザーの環境が設定された状態でスクリプトが実行されるとは限りませんsu

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

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

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

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

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


1
-Iを設定できるPERLOPTを忘れないでください。また、base.pmやlocal :: libなどは、暗黙的にリストしたものを使用します。
brian d foy 10/03/26

1
@brian-use :: baseは、IIRCの下にある「require」のためにそれを使用します。私はlocal :: libに詳しくありません。それが何であるかを理解するためにもっと読む必要があります
DVK

3
また、これを本当に良い答えにするためには、いつそれぞれを使うべきかを人々に知らせる必要があります。彼らにどのようにできるかについて10のオプションを与えるだけではあまり役に立ちません。:)
brian d foy

PS誰でも、回答を自由に編集して、-I / use libを介して2番目のアーキテクチャ固有のディレクトリを含めるようにしてください。私は後で自分でそうするつもりでしたが、今のところオフラインにする必要があります。
DVK 2010年

@brian-PERLOPTを追加しました。私が投稿してリンクした@ INC / findingモジュールファイルのFAQには、base.pmやその他の「いつ@INCが使用されるのか」という項目の方が適しているので、ここに配置します。
DVK 2010年

18

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

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

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


6

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.