3

ユーザーが必要なモジュールを欠いていることを検出し、何をインストールする必要があるかを説明するわかりやすいエラー メッセージを出力したいと考えています。

これまでのところ、スクリプトの先頭にこれを入れてみました:

eval {
    use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
};
if ($@) {
    die "Error: IO::Uncompress::Gunzip not installed: $@";
}

しかし、Perl は "die" 行ではなく "use" 行で停止しているようで、エラー メッセージを表示しません。

4

3 に答える 3

10
use IO::Uncompress::Gunzip qw( gunzip $GunzipError );

の略です

BEGIN {
   require IO::Uncompress::Gunzip;
   import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
}

BEGINブロックはコンパイルされるとすぐに評価されます。つまり、コードは次のことを行います。

  1. コンパイル段階:
    1. evalステートメントを コンパイルします。
      1. コンパイルされBEGINたブロック。
        1. コンパイルrequire IO::Uncompress::Gunzip;
        2. コンパイルimport IO::Uncompress::Gunzip qw( gunzip $GunzipError );
      2. ブロックを評価BEGINします。
        1. 評価require IO::Uncompress::Gunzip;
        2. 評価import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
    2. ifステートメントをコンパイルします。
  2. 実行フェーズ:
    1. (空) evalステートメントを評価します。
    2. ifステートメントを評価します。

ステップ 1.1.2.1 で例外が発生した場合、evalステップ 2.1 の実行ではキャッチされません。


ソリューション:

あなたは同等のものから始めました

BEGIN {
   require IO::Uncompress::Gunzip;
   import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
}

requireキャッチしたいのはエラーなので、のeval周りにを追加するだけrequireです:

BEGIN {
   eval { require IO::Uncompress::Gunzip }
      or die "Error: IO::Uncompress::Gunzip not installed: $@";

   import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
}

代わりに をuse使用して、コンパイル (および評価) を遅らせることもできます。eval EXPReval BLOCK

BEGIN {
   eval 'use IO::Uncompress::Gunzip qw( gunzip $GunzipError ); 1'
      or die "Error: IO::Uncompress::Gunzip not installed: $@";
}

(モジュールがインストールされているかどうかを調べる良い方法があればいいのにと思います。最初の解決策でさえ他のエラーをキャッチしますが、2番目の解決策はさらに多くのエラーをキャッチします。)

于 2012-06-13T18:39:45.783 に答える
5

ここで起こっていることは、モジュールがブロックuse内にあるという事実に関係なく、コンパイル時にモジュールが d されているということです。eval

これが、フォームからフォームへと変更するというnaab の提案が機能する理由でもあります。式は実行時に評価されます。を に変更すると、実行時にモジュールのロードが試行されます。eval BLOCKeval EXPRuserequire

eval {
    require IO::Uncompress::Gunzip;
    IO::Uncompress::Gunzip->import( qw/gunzip $GunzipError/ ) ;
};
if ($@) {
    die "Error: IO::Uncompress::Gunzip not installed: $@";
}

出力

エラー: IO::Uncompress::Gunzip がインストールされていません: @INC に IO/Uncompress/Gunzip.pm が見つかりません (@INC には C:/Perl/site/lib C:/Perl/lib が含まれています) at - line 2.

于 2012-06-13T18:34:01.933 に答える
0

Class::Load の try_load_class ( CPAN )をチェックしてください

use Class::Load;
die "Error: IO::Uncompress::Gunzip not installed" if 
    (! try_load_class (IO::Uncompress::Gunzip));

しかし、私が知る限り、Class::Load で qw(gunzip $GunzipError) をインポートすることはできません。

于 2012-12-17T21:29:06.653 に答える