Perlモジュールが検索される場所に影響を与えるすべての方法は何ですか?または、Perlの@INCはどのように構築されますかますか?
ご存じのとおり、Perlは@INC
ディレクトリ名を含む配列を使用して、Perlモジュールファイルを検索する場所を決定します。
StackOverflowに包括的な「@INC」FAQタイプの投稿はないようですので、この質問は1つとして意図されています。
@INC
ではなく、実行時に追加する方法を伝えるだけの包括的なものではありません。
Perlモジュールが検索される場所に影響を与えるすべての方法は何ですか?または、Perlの@INCはどのように構築されますかますか?
ご存じのとおり、Perlは@INC
ディレクトリ名を含む配列を使用して、Perlモジュールファイルを検索する場所を決定します。
StackOverflowに包括的な「@INC」FAQタイプの投稿はないようですので、この質問は1つとして意図されています。
@INC
ではなく、実行時に追加する方法を伝えるだけの包括的なものではありません。
回答:
この配列の内容がどのように構築され、Perlインタープリターがモジュールファイルを検索する場所に影響を与えるように操作できるかを見ていきます。
デフォルト @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
環境変数 PERL5LIB
(またはPERLLIB
)
Perl は、シェルの環境変数(定義されていない場合は使用されます@INC
)に含まれているPERL5LIB
(コロンで区切られた)ディレクトリのリストを先頭に付加しPERLLIB
ます。@INC
after 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 .
-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章を参照)。
Perlプリペンド @INC
は、を介して渡されたディレクトリのリストをしuse lib
ます。
プログラム内:
use lib ("/dir1", "/dir2");
コマンドラインで:
perl -Mlib=/dir1,/dir2
via からディレクトリを削除@INC
no lib
することもできます。
@INC
通常のPerl配列として直接操作できます。
注:@INC
はコンパイル段階で使用されるためBEGIN {}
、use MyModule
ステートメントの前のブロック内で実行する必要があります。
を介してディレクトリを最初に追加しunshift @INC, $dir
ます。
を介してディレクトリを最後に追加しpush @INC, $dir
ます。
Perl配列でできることは他に何でもしてください。
注:ディレクトリは、この回答にリストされている順序でシフトさ@INC
れません。たとえば、デフォルト@INC
はリストの最後にあり、前にPERL5LIB
、前に-I
、前にuse lib
し、直接@INC
操作があり、後者の2つは、Perlコード内の順序で混在しています。
@INC
ですか?@INC
Stack 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コードを含めることができます)。
すでに述べたように、@ 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によってエクスポートされます。