web-dev-qa-db-ja.com

Perlスクリプトは同じディレクトリでモジュールを見つけるにはどうすればよいですか?

プロセス名/ユーザー名に基づいてプロセスを強制終了する新しいPerlスクリプトを最近作成し、クラスを使用して拡張して、他のプログラムでプロセスコードを再利用できるようにしました。私の現在のレイアウトは-

/home/mutew/src/prod/pskill       <-- Perl script
/home/mutew/src/prod/Process.pm   <-- Package to handle process descriptions

どこからでもスクリプトにアクセスするために、$ PATH変数に〜/ src/prodを追加しました。常駐ディレクトリ以外のディレクトリからスクリプトを実行すると、「@ INCでProcess.pmが見つかりません」になります(/ usrの共有ディレクトリ以外では、@ INCには現在のディレクトリのみが含まれます- 「。」)。私が使用している1つの回避策は、use libディレクティブです-

use lib '/home/mutew/src/prod';

しかし、これは主要な移植性の問題です。変更せずにスクリプトを他のシステムにエクスポートできるソリューションはありますか?


[〜#〜] edit [〜#〜]

  1. そのシンプルさとコアモジュールの使用法のため、正しい答えとして「depesz」の答えを選びました。
  2. brian d foyの答えは、同じことを達成する他の方法(TMTOWTDI)を示唆していますが、perlfaq8での彼の貢献はこの質問を絶対に冗長にします。
49
aks

私が見つけた最も簡単なアプローチは、FindBinモジュールを使用することです。このような:

use FindBin;
use lib $FindBin::Bin;

一般に、プログラムがwhatever/binにあり、ライブラリがwhatever/libにあるような方法でスクリプトを提供することを好む

これらの状況では、もう少し複雑なアプローチを使用します。

use Cwd qw(abs_path);
use FindBin;
use lib abs_path("$FindBin::Bin/../lib");

Abs_path呼び出しは、@ INCにwhatever/libを含め、whatever/bin /../ libを含めないようにすることです。わずかな変更ですが、エラーメッセージを読みやすくします。

51
user80168

なぜ単純な解決策なのか興味があります

use File::Basename;
use lib dirname (__FILE__);
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule;

現れなかった。ファイルがメインの実行可能Perlスクリプトではなく、単に実行不可能なPerlモジュールである場合、FindBinモジュールにはいくつかの問題があるようです。少なくとも、これが documentation のコメントの解釈です。実際にテストしませんでした。

このPerlファイルの場所に関連する他のパスを設定するには、次のようにします

use File::Basename;
use lib dirname (__FILE__) . "/MyModules";
57
Andreas Schuh

perlfaq8 から 「実行時にディレクトリをインクルードパス(@INC)に追加するにはどうすればよいですか?」 から。この問題に関する質問に対する他の回答もいくつかあります。


実行時にインクルードパス(@INC)にディレクトリを追加するにはどうすればよいですか?

以下に、環境変数、ランタイムスイッチ、コード内ステートメントなど、インクルードパスを変更する推奨方法を示します。

pERLLIB環境変数

$ export PERLLIB=/path/to/my/dir
$ Perl program.pl

perl5LIB環境変数

$ export Perl5LIB=/path/to/my/dir
$ Perl program.pl

perl -Idirコマンドラインフラグ

$ Perl -I/path/to/my/dir program.pl

use libプラグマ:

use lib "$ENV{HOME}/myown_perllib";

最後は、マシン依存のアーキテクチャについて知っているため、特に役立ちます。 lib.pmプラグマティックモジュールは、Perlの5.002リリースに最初に含まれました。

13
brian d foy

Par :: Packer を見てください。スクリプトのすべての依存関係を含む実行可能ファイルを作成します。配布が簡単になります。また、システムにインストールできるモジュールのバージョンをユーザーに提供することもできます。標準のCPANスタイルのディストリビューションを作成するために必要なすべてのファイルを簡単にビルドする方法については、 Module :: Starter を参照してください。

3
Chas. Owens

-Iフラグを使用して、Perlに任意のディレクトリを表示させることができます。ここで、-I@INCの略で、Perlがモジュールを探すパスの配列です。 -Iを使用すると、指定されたパスがこの実行の@INC配列に追加されます。

例えば:

Perl -I lib bin/script.pl

libには、使用したいモジュールが含まれています。

これはPerl 5で機能することを知っています。他のバージョンについてはわかりません。

2
Vikas

すでに述べた解決策に加えて:

  1. findBin/libを使用します
  2. Perl Faq 8 実行時にインクルードパス(@INC)にディレクトリを追加するにはどうすればよいですか?

(/ usr/local/lib/site_Perl /または@INCの他の場所で)モジュールを開発/テストするときに使用する「最も簡単なアプローチ」(™)は、次のようにモジュールをロードする前に@INCを変更することです。

#!/usr/bin/Perl
use strict;
use warnings;
# Modify @INC prior to module loading.
BEGIN { unshift @INC, '.'; }
use YourModuleInCWD;

現在の作業ディレクトリを@INCに追加しますか?-PerlMonks

1
Robert

相対リンクを絶対リンクに変換して@INCに追加するには、通常ex :: libを使用します。もちろん、これは、スクリプトを実行する予定のすべてのマシンで、スクリプトとモジュールの相対位置を同一に保つことを計画している場合にのみ役立ちます。

0
Ya. Perelman