Perl モジュールを使用する前に、そのモジュールがあるかどうかを確認するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/251694

  •  05-07-2019
  •  | 
  •  

質問

次の Perl コードがあります。 Term::ReadKey 端末の幅を取得します。私の NetBSD ビルドにはこのモジュールが欠落しているため、モジュールが欠落している場合の端末の幅をデフォルトの 80 にしたいと考えています。

モジュールが利用可能かどうかを事前に知って、条件付きでモジュールを使用する方法がわかりません。現在の実装は、見つからないというメッセージを表示して終了します。 Term::ReadKey それが存在しない場合。

#/usr/pkg/bin/perl -w
# Try loading Term::ReadKey
use Term::ReadKey;
my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
my @p=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97);
my $plen=$#p+1;
printf("num |".("%".int(($wchar-5)/$plen)."d") x $plen."\n",@p);

私はNetBSDでPerl 5.8.7を使用しており、Cygwinで5.8.8を使用しています。これをより効果的に実装するのを手伝っていただけますか?

役に立ちましたか?

解決

別のモジュールを必要としない最低限のソリューションは次のとおりです。

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

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

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

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

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

他のヒント

CPANモジュール Module :: Load :: Conditional を確認します。 。必要なことを行います。

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

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

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) {
    # ...
}
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 :: ... が適切にロードされた場合にのみ実行されます。

変数を使用すると機能しないと思います。 このリンクをチェックして、変数でどのように使用できるかを説明してください

$class = 'Foo::Bar';
        require $class;       # $class is not a bareword
    #or
        require "Foo::Bar";   # not a bareword because of the ""

require関数は" Foo :: Bar"を探します。 @INC配列のファイルで、" Foo :: Bar"が見つからないと文句を言いますそこ。この場合、次のことができます。

 eval "require $class";
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top