Perlモジュールが検索される場所に影響を与えるすべての方法は何ですか?または、Perlの@INCはどのように構築されますか?
ご存知のように、Perlは@INC
ディレクトリ名を含む配列を使用してPerlモジュールファイルを検索する場所を決定します。
StackOverflowには包括的な「@INC」FAQタイプの投稿がないようですので、この質問は1つとして意図されています。
Perlモジュールが検索される場所に影響を与えるすべての方法は何ですか?または、Perlの@INCはどのように構築されますか?
ご存知のように、Perlは@INC
ディレクトリ名を含む配列を使用してPerlモジュールファイルを検索する場所を決定します。
StackOverflowには包括的な「@INC」FAQタイプの投稿がないようですので、この質問は1つとして意図されています。
この配列の内容がどのように構築され、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
に含まれるディレクトリ(コロンで区切られた)のリストをプリペンドします。afterおよびenvironment変数の内容が有効になったことを確認するには、を実行します。PERL5LIB
PERLLIB
@INC
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スクリプトの最初の行(shebang)を介して渡します。
#!/usr/local/bin/perl -w -I /my/moduledir
PERL5OPT
それを(または)環境変数の一部として渡します( PerlPERLOPT
のプログラミングの19.02章を参照) 。
@INC
Perlは、を介して渡されたディレクトリのリストをプリペンドしuse lib
ます。
プログラムの場合:
use lib ("/dir1", "/dir2");
コマンドライン:
perl -Mlib=/dir1,/dir2
を介してディレクトリを削除する@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
ですか?Stack Overflowに関する包括的なFAQタイプの投稿はないようです@INC
ので、この質問は1つとして意図されています。
ディレクトリ内のモジュールをサイトの多くの/すべてのスクリプトで使用する必要がある場合、特に複数のユーザーが実行する必要がある場合は、そのディレクトリを@INC
Perlバイナリにコンパイルされたデフォルトに含める必要があります。
ディレクトリ内のモジュールが、ユーザーが実行するすべてのスクリプトに対して特定のユーザーによって排他的に使用される場合(または、Perlの再コンパイルが@INC
以前の使用例でデフォルトを変更するオプションではない場合)PERL5LIB
、通常はユーザーのログイン時にユーザーを設定します。
注:通常のUnix環境変数の落とし穴に注意してください。たとえば、特定のユーザーとしてスクリプトを実行しても、そのユーザーの環境が設定された状態でスクリプトを実行することは保証されませんsu
。
ディレクトリ内のモジュールを特定の状況でのみ使用する必要がある場合(たとえば、スクリプトが開発/デバッグモードで実行される場合)、PERL5LIB
手動で設定するか、-I
オプションをperlに渡すことができます。
モジュールを特定のスクリプトにのみ使用する必要がある場合は、モジュールを使用するすべてのユーザーが、プログラム自体でuse lib
/ no lib
pragmasを使用します。また、実行時に検索するディレクトリを動的に決定する必要がある場合にも使用する必要があります。たとえば、スクリプトのコマンドラインパラメータやスクリプトのパスから使用します(非常に優れた使用例については、FindBinモジュールを参照してください)。
複雑なロジックに従ってディレクトリを操作する必要がある場合は、 /プラグマ@INC
の組み合わせで実装するには扱いにくいため、ブロック内または操作用に指定された専用ライブラリ内で直接操作を使用します。これはスクリプトで使用する必要があります。 (s)他のモジュールが使用される前。use lib
no lib
@INC
BEGIN {}
@INC
この例は、prod / uat / devディレクトリ内のライブラリを自動的に切り替えることです。devやUATから欠落している場合は、prodでウォーターフォールライブラリをピックアップします(最後の条件により、標準の「use lib+FindBin」ソリューションがかなり複雑になります。Aこのシナリオの詳細な説明は、ベータ版Perlスクリプトからベータ版Perlモジュールを使用するにはどうすればよいですか?にあります。
直接操作するための追加のユースケース@INC
は、サブルーチン参照またはオブジェクト参照を追加できるようにすることです(はい、バージニア州では、@ INCのサブルーチン参照はいつ呼び出されますか?で@INC
説明されているように、ディレクトリ名だけでなくカスタムPerlコードを含めることができます)。
上記の場所に加えて、OSXバージョンのPerlにはさらに2つの方法があります。
/Library/Perl/x.xx/AppendToPathファイル。このファイルにリストされているパスは、実行時に@INCに追加されます。
/Library/Perl/x.xx/PrependToPathファイル。このファイルにリストされているパスは、実行時に@INCの前に付加されます。
すでに述べたように、@ INCは配列であり、必要なものを自由に追加できます。
私のCGIRESTスクリプトは次のようになります。
#!/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によってエクスポートされます。