2016-10-14 18 views
1

Perlファイルで使用されている欠落しているモジュールを、エラーとして取得する代わりに事前に報告する方法はありますか?Perlモジュールがないことを確認して報告する

私のPerlプログラムにはuse Digest::MD5,use File::DosGlobというモジュールがあります。ユーザーがスクリプトを実行するたびに、システムに特定のモジュールがインストールされていないとエラーが発生します。彼らは@INCによって与えられるデフォルトのエラーメッセージを理解できませんでした。ですから、これらのモジュールをインストールしてスクリプトを実行する必要があることを明確に伝えたいと思います。

答えて

5

a BEGIN blockを使用して独自の検証を構築できます。それらはコンパイル時に実行され、ちょうどuseのようです。

BEGIN { 
    require Foo; 
    Foo->import; 
} 

次のコードは、単一BEGINですべてuse文を置き換えるとeval内でそれらを配置します:use Fooは、本質的に、このように他ならないことに注意してください。これは本質的にtry/catchメカニズムのようなものです。

は、私たちは、引数がa barewordある場合のみ、パスにコロン::とパッケージ名から変換しrequireので(この辺り悪と考えられている)文字列evalを必要としています。しかし、$moduleに名前があるので、それは文字列なので、に従ってevalに配置する必要があります。

文字列evalが失敗した場合は、dieです。それは外側のevalブロックによって捕らえられ、[email protected]が設定されています。モジュール名が含まれているかどうかを確認することができます。この場合、そのモジュールがインストールされていないために失敗したと考えられません。この小切手はもう少し精巧であるかもしれません。

私たちは$failsの失敗を追跡し、もしあれば、私たちは停止します。私は私が持っていないASDFを、含ま上

#!/usr/bin/perl 
use strict; 
use warnings; 

# all our use statements go here 
BEGIN { 
    my $fails; 
    foreach my $module (qw/Digest::MD5 File::DosGlob ASDF/) { 
     eval { 
      eval "require $module" or die; # because $module is not a bareword 
      $module->import; 
     }; 
     if ([email protected] && [email protected] =~ /$module/) { 
      warn "You need to install the $module module"; 
      $fails++; 
     } 
    } 
    exit if $fails; 
} 

# ... 

ので、実行するとき、それはあなたが/home/code/scratch.plライン1335で空自モジュールをインストールする必要が

言うだろう。

メッセージをもう少し冗長にしたい場合があります。ユーザーがPerlがモジュールを見つけることができないときに出るデフォルトのエラーメッセージを理解できない場合は、そこに物事をインストールする方法に関するガイドを含むことが賢明かもしれません。

リストされた両方のモジュールがa whileのPerlに含まれていることに注意してください(2002年3月以降読んでください)。では、なぜこれらのモジュールでこれをしたいのですか?

$ corelist Digest::MD5 

Data for 2014-09-14 
Digest::MD5 was first released with perl v5.7.3 

$ corelist File::DosGlob 

Data for 2014-09-14 
File::DosGlob was first released with perl 5.00405 

より良い方法をインストールすることができ分布として、あなたのプログラムを出荷し、Makefileのかcpanfileや依存関係を示しています似たようなを含めるだろう。新しいモジュールを起動する方法については、perlnewmodのガイドがあります。明らかにCPANにアップロードしたくないのですが、基本は同じです。

このようにすると、すべての依存関係が自動的にインストールされます。

+0

_perlnewmod_に言及してくれてありがとう。私はいつもCPANがどのように埋められているのか疑問に思いました。 – PerlDuck

+0

その文書@PerlDuckだけではありません。新しいディストリビューションを開始するためのさまざまなツールや、いくつかのガイドがあります。多分、これはCPANで何かをリリースする良い時期です。 PAUSEアカウントを作ってみましょう。 :) – simbabque

+0

私はmakefileやcpanfileに慣れていないので、Beginは1つのファイルのために働いています。ありがとうございます。しかし、フォルダ内のすべてのperlファイルをチェックするにはどうすればいいのですか? – VSr

1

あなたの質問は、「あらかじめ」ということを意味するものではありません。 Perlプログラムの構文が正しいと直接モジュールが解決されている含まれているかどうかを確認するには、

perl -c <perl-program.pl> 

を使用これは、ファイルの構文をチェックし、あなたのコードで任意のモジュールuse dが存在することを保証します。ただし、依存関係ツリー全体を推移的にチェックするのではなく、perl-program.plに記載されているものだけを確認します。

+2

モジュール内でモジュール 'use'dを使用している場合、コードではそれを使用します。実行できないのは、実行時に 'require'を使ってロードされるモジュールをチェックすることです。 – mbethke

+1

'test1.pl'が同じディレクトリで' test2.pm'を使い、 'test2.pm'が悪い' use'ステートメントを持っている場合、 'perl -c test2.pm'だけで捕捉され、 perl -c test1.pl' –

+0

perl 5.24で動作します。私はそれがいつもそうだったと確信しています。 '$ echo"はXを使用します; " > x.pl;エコー "パッケージX;使用Y;" > X.pm; perl -c x.pl'は '@ INCでY.pmを見つけることができません 'という結果になります – mbethke

5

Devel::Modlistを使用すると、プログラムに必要なモジュールがすべて一覧表示されます。

perl -d:Modlist test.pl 

あなたのように、スクリプトに使用できるユーティリティが付属していますscandeps.pl別のモジュールModule::ScanDepsあります:sanity checking your Perl code using perl -c is dangerous、慎重にそれを使用することを

scandeps.pl test.pl 

注意。

関連する問題