2016-02-29 154 views
0

我寫了一個perl程序,它在內部調用三個perl模塊。我的主管在審查代碼後問我添加了全局異常處理。我不明白他的意思。他還表示使用Eval來完成這一任務。我不確定如何使用Eval,以便捕獲enire perl模塊中的任何異常。任何人都可以通過提供鏈接或提供解釋來幫助我? 在此先感謝。perl中的全局級異常處理

+1

這可能有所幫助:[在Perl中處理異常的最佳方式是什麼?](http://stackoverflow.com/questions/4006267/what-is-the-best-way-to-handle-exceptions-in -perl) – Amadan

+4

我想你可能不得不問你的主管!就我而言,Perl中的全局異常處理包括通過將子例程分配給'$ SIG {__ DIE __}'來編寫'die'處理程序(如[perlvar](http://perldoc.perl.org/中所述) perlvar.html#通用變量))。這是真的只適合調試。另一方面,'eval'只允許你在代碼塊中處理錯誤。我猜如果你有一個執行整個程序的main()子程序,就像在C中一樣,那麼你可以把它放在'eval {main(); ''塊,但我不確定我看到了這一點。 – Borodin

+0

您從[Amadan](http://stackoverflow.com/users/240443/amadan)和[Borodin](http://stackoverflow.com/users/622310/borodin)獲得了很好的建議和信息,其評論也表達了事實並不清楚你的情況是什麼; 「全局異常處理」對我來說是一個陌生的術語。這裏有幾個問題:你從這些模塊調用函數多少/經常?在什麼級別 - 埋在深層次的內部或在main ::'中?什麼是模塊?整個項目的規模和結構如何?簡而言之,我的意思是。 – zdim

回答

1

對於每一個他希望我有一個異常處理,如果出現錯誤,將被高亮顯示其中程序,它讓我們變得易於調試。

當未捕獲的異常發生時,它將打印到STDERR。您的突出顯示要求已得到滿足。

異常消息已經包含了引發它們的行號(除非明確禁止),所以一些幫助調試的信息已經可用。

$ perl -e'sub f { die "bar" } f("foo")' 
bar at -e line 1. 

添加use Carp::Always;到腳本將導致,以及提供在堆棧中,提供更多的信息。

$ perl -e'use Carp::Always; sub f { die "bar" } f("foo")' 
bar at -e line 1. 
     main::f("foo") called at -e line 1 
0

你給的問題似乎不準確。 「全球」和eval有些矛盾,因爲 Borodin在他的評論中解釋。 ikegami的答案給出了另一種做「全球化」的方法。然而,自提eval具體這裏是一個非常基本的使用情況的破壞。

您使用eval代碼塊(或表達式,但這不是你想要的)。如果一個die被拋出該塊內的任何地方,eval捕獲的意義,你控制回來,程序不會死。變量[email protected]被填充了錯誤消息。然後,您可以詢問發生的情況,打印出診斷信息,並可能從錯誤中恢復。

eval { run_some_code(@args) }; 
if ([email protected]) { 
    carp "Error in `run_some_code()`: [email protected] --"; 
    # Do further investigation, print, recover ... 
} 

您可以在eval塊中的任何代碼上面,它不一定是一個函數調用。請注意,eval本身返回傳達發生的事情的數值(除了設置[email protected])。

至於你的問題陳述中的「全局」,有一點可以想到,你在main::的層次上使用eval - 在其中包含任何從模塊調用函數的子。

關於例外情況的一個至關重要的事情是它們「冒泡」。當die(Perl的唯一的例外),在子拋出和呼叫者沒有eval它,它去了電話...鏈條最終顯示main::了,如果沒有抓到(eval -ed)有然後程序死亡。所以你可以在main::頂級電話eval,並瞭解是否有以下任何地方出錯。

eval { top_level_call(); }; 
if ([email protected]) { 
    warn "Error from somewhere in `top_level_call(): [email protected]"; 
} 

# Functions 
sub top_level_call { 
    # doing some work ... 
    another_sub(); 
    # doing more ... 
} 
sub another_sub { 
    # do work, no eval checks 
} 

如果錯誤觸發dieanother_sub()其處理髮生立即停止,並且控制返回到調用者,所述top_level_call()。由於該子程序沒有檢查(在那裏沒有eval),所以它的執行在那個點停止,並且控制返回到它的調用者(在這個例子中是main::本身)。所以它最終擊中main::eval-在那裏讓你知道錯誤,你的程序不會退出。

也許這就是使用eval「全局」異常處理的含義。

如果這是你需要做的事情,你可以沿着這些路線做更多的事情。初學者請參閱eval。 通過澄清更新您的問題,讓您在此處獲得更多討論。

實際上,我認爲您需要了解eval以及一些「全局」錯誤報告,然後請您的主管進行澄清和/或示例,如Borodin所示。