55

Term::ReadKey端末の幅を取得するために依存する Perl コードがあります。インストールにこのモジュールがないため、例外をスローするのではなく、モジュールが存在しない場合にデフォルトを提供したいと考えています。

利用可能かどうかを事前に知らずに、オプション モジュールを条件付きで使用するにはどうすればよいですか。

# but only if the module is installed and exists
use Term::ReadKey;
...

どうすればこれを達成できますか?

4

8 に答える 8

97

別のモジュールを必要としない必要最小限のソリューションを次に示します。

my $rc = eval
{
  require Term::ReadKey;
  Term::ReadKey->import();
  1;
};

if($rc)
{
  # Term::ReadKey loaded and imported successfully
  ...
}

以下のすべての回答 (これより下にあることを願っています! :-)eval { use SomeModule }が間違っていることに注意してください。これは、useステートメントがコード内のどこにあるかに関係なく、コンパイル時に評価されるためです。したがって、SomeModuleが利用できない場合、スクリプトはコンパイル時にすぐに終了します。

(ステートメントの文字列 evaluseも機能します ( ) が、 /ペアが同じことを行い、起動時にコンパイル時に構文チェックされるeval 'use SomeModule';場合、実行時に新しいコードを解析してコンパイルしても意味がありません。)requireimport

eval { ... }最後に、ここでのandの使用は$@、この例の目的のために簡潔であることに注意してください。実際のコードでは、Try::Tinyのようなものを使用するか、少なくともそれが対処する問題に注意する必要があります

于 2008-10-30T21:07:56.050 に答える
11

CPAN モジュールModule::Load::Conditionalを確認してください。それはあなたが望むことをします。

于 2008-10-30T20:53:46.890 に答える
7

古典的な答え(少なくとも「use」が存在するずっと前のPerl 4にまでさかのぼります)は、モジュールを「require()」することでした。これは、コンパイル時ではなくスクリプトの実行時に実行され、成功または失敗をテストして適切に対応できます。

于 2008-10-30T21:23:59.000 に答える
4

また、特定のバージョンのモジュールが必要な場合:

my $GOT_READKEY;
BEGIN {
    eval {
        require Term::ReadKey;
        Term::ReadKey->import();
        $GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30;
    };
}


# elsewhere in the code
if ($GOT_READKEY) {
    # ...
}
于 2008-11-04T10:35:48.817 に答える
4
if  (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}

また

if  (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}

注: は適切にロードされた1;場合にのみ実行されます。require Term::...

于 2009-05-05T06:43:47.767 に答える