2016-10-14 35 views
1

有什麼方法可以事先報告Perl文件中使用的缺失模塊,而不是將其作爲錯誤報告。檢查並報告缺少Perl模塊

我在我的Perl程序中有類似use Digest::MD5,use File::DosGlob模塊。每當用戶運行腳本時,如果他們的系統中沒有安裝特定的模塊,他們就會收到錯誤信息。他們無法理解@INC給出的默認錯誤消息。所以我想清楚地告訴他們需要安裝這些模塊來運行腳本。

回答

5

您可以使用a BEGIN block構建自己的驗證。這些是在編譯時運行的,就像use一樣。請記住,use Foo基本上沒有別的,因爲這:

BEGIN { 
    require Foo; 
    Foo->import; 
} 

下面的代碼將取代所有use語句與單個BEGIN並將它們放置一個eval內。這基本上就像一個try/catch機制。

我們需要串eval(這被認爲是邪惡在這裏),因爲require只用冒號::爲路徑包名稱轉換,如果參數爲a bareword。但是因爲我們的名稱是$module,它是一個字符串,所以我們需要根據require's docs將它放入eval

如果該字符串eval失敗,我們die。這被外部eval區塊所捕獲,並設置了[email protected]。然後我們可以檢查它是否包含我們的模塊名稱,在這種情況下,我們天真地認爲失敗是因爲該模塊未安裝。這項檢查可能會更詳細。

我們跟蹤$fails中的任何故障,如果有任何故障,我們將停止。

#!/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; 
} 

# ... 

上面我包括ASDF,而我沒有,所以在運行時,它會說

您需要在/home/code/scratch.pl線1335安裝ASDF模塊。

您可能希望使該消息更加冗長。如果您的用戶無法理解Perl在找不到模塊時提供的默認錯誤消息,那麼可以明智地包含關於如何在此處安裝東西的指南。

請注意,您列出的兩個模塊已包含在Perl中,用於a while(閱讀:自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

除了那個doc @PerlDuck還有很多。有各種工具可以啓動新的發行版,還有一些指南。也許這是在CPAN上發佈一些東西的好時機。開始建立一個暫停帳戶。 :) – simbabque

+0

我真的不熟悉生成文件或cpanfile,開始工作的單個文件謝謝你,但如果我想檢查文件夾中的所有perl文件如何可以做 – VSr

1

你的問題並不清楚「預先」的含義。要檢查Perl程序的語法是正確的,直接計入模塊解析,使用

perl -c <perl-program.pl> 

這將檢查文件的語法,並確保您的代碼D任何模塊use存在。但是,它不會過渡檢查整個依賴關係樹,只有在perl-program.pl中提到的依賴關係樹。

+2

如果你的意思是你的代碼使用模塊'use'd,那麼是的,它是的。它不能做的是檢查在運行時使用'require'加載的模塊。 – mbethke

+1

如果'test1.pl'在同一個目錄下使用'test2.pm',並且'test2.pm'有一個糟糕的'use'語句,它將只被一個expicit'perl -c test2.pm'捕獲,而不是' perl -c test1.pl' –

+0

適用於perl 5.24,我非常確定它一直如此。 '$ echo'使用X;「 > x.pl; echo「package X; use Y;」 > X.pm; perl -c x.pl'導致'Can not locate Y.pm in @ INC' – mbethke