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
(定義されていない場合は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 .
-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章を参照)
lib
プラグマ で渡します
Perlは、@INC
を介して渡されたディレクトリのリストを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
にunshiftedされます。デフォルトの@INC
は、リストの最後にあり、Perl5LIB
が前にあり、-I
が前にあり、use lib
が前にあり、@INC
が直接操作されます。
@INC
にないディレクトリでPerlモジュールを「使用」する方法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のサブルーチン参照はいつ呼び出されますか? )。
上記の場所に加えて、OS XバージョンのPerlにはさらに2つの方法があります。
/Library/Perl/x.xx/AppendToPathファイル。このファイルにリストされているパスは、実行時に@INCに追加されます。
/Library/Perl/x.xx/PrependToPathファイル。このファイルにリストされているパスは、実行時に@INCの前に追加されます。
すでに述べたように、@ 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によってエクスポートされます。