3

スクリプトでカスタム モジュールを使用しており、それらを Perllibディレクトリの外に保存する必要があります。したがって、Perl スクリプト ( *.pl) では、次のブロックを使用してそれらを に含めます@INC

BEGIN {
  use FindBin qw($Bin);
  push @INC, "$Bin/../ModulesFolder1";
  push @INC, "$Bin/../ModulesFolder2";
}

しかし、他の Perl モジュール ( *.pm) 内でモジュールを使用する必要もあり、私が理解しているようFindBinに、スクリプトでのみ機能します。そこで、そのブロックを次のように変更します。

BEGIN {
  push @INC, catdir( dirname( $INC{'ThisModule.pm'} ), qw( .. ModulesFolder1 ) );
  push @INC, catdir( dirname( $INC{'ThisModule.pm'} ), qw( .. ModulesFolder2 ) );
}

動作しますが、少し問題があります。私は EPIC プラグインを使用して Eclipse でコーディングしていますが、「BEGIN ブロックに何かがあり、コンパイラが途中で中止する場合、構文エラーは EPIC に報告されません」ということで、モジュール内の Perl 構文チェックが失われます。
したがって、FindBin(スクリプト内で)ブロック内で関数( などcatdir)を使用する必要はなくBEGIN{}、次のコードの構文チェックは正しく行われます。PERL5LIBさらに、追加の準備なしで同僚のマシンでスクリプトを使用できるように、環境変数 ( など) を変更したくありません。

他のモジュール内でカスタム Perl モジュールを使用し、同時に EPIC 構文チェックを妨害しない適切な方法は何ですか? それとも、まったく別の方法でモジュールを含める必要があるのでしょうか?

4

4 に答える 4

4

@INCモジュールでの変更には強く同意しません。それはあらゆる種類の頭痛を引き起こします。スクリプト(またはPERL5LIB環境変数を介した呼び出しプロセス)を@INC正しく設定します。

script.pl

use FindBin qw( $RealBin );
use lib
   "$RealBin/../ModulesFolder1",
   "$RealBin/../ModulesFolder2";

use ModuleInFolder1;

ModuleInFolder1.pm

use ModuleInFolder2;  # Works fine.

EPICについては、次のようにします。

  1. プロジェクトを右クリックします。
  2. プロパティ
  3. Perlインクルードパス
  4. ${project_loc}/ModulesFolder1、 リストに追加する
  5. ${project_loc}/ModulesFolder2、 リストに追加する

(私は文字通り14文字を意味し${project_loc}ます。それはEPICにとって何かを意味します。プロジェクトを移動しても機能し続けます。)


PS —スクリプトへのシンボリックリンクを使用できるため$RealBinよりも優れています。$Bin

PS —__FILE__より適切です$INC{'ThisModule.pm'}

于 2012-07-27T17:56:25.190 に答える
1

Eclipse についてはわかりませんが、use lib@INCを使用するか (おそらく動作しないでしょう。コンパイル時に変更されます) PERL5LIB、ライブラリ フォルダーを指すように環境変数を設定できます。

于 2012-07-27T11:56:05.550 に答える
1

PERL5LIB環境変数を設定します。use または require するたびに、Perl はそこにリストされているすべてのディレクトリをチェックします。

または、必要なすべてのカスタム モジュールをスクリプトのディレクトリの下に配置して、 で相対パスを使用できるようにしますuse lib。また、最上位ディレクトリから再帰的にパックするだけで、すべてを別の PC に転送するためのバンドルをすばやく作成することもできます。

于 2012-07-27T11:56:32.103 に答える
0

別の解決策 (同僚から) - モジュールで行う変更:

sub path_to_current_module() {
  my $package_name = __PACKAGE__ .'.pm';
  $package_name =~ s#::#/#g;

  for my $path ( @INC ) {
    # print "\$path == '$path'\n";
    if ( -e catfile( $path, $package_name ) ) {
      return $path;
    }
  }

  confess;
}

BEGIN {
  my $path_to_current_module = path_to_current_module();
  push @INC, catdir( $path_to_current_module, qw( .. ModulesFolder1 ) );
  push @INC, catdir( $path_to_current_module, qw( .. ModulesFolder2 ) );
}

古い方法 (質問で説明) では、Perl は現在のモジュール名を見つけることができなかったようです。これが、ブロック内のエラーによって中断された@INC理由です。そして、記述されたサブルーチンは、現在のモジュールへの実際のパスを決定するのに役立ちます。また、現在のファイル名に依存せず、別のモジュールにコピーできます。perl -cBEGIN

于 2012-07-30T16:48:24.183 に答える