2010-05-19 76 views
14

我學習的Perl,並在很多我看到錯誤的例子是這樣Perl中錯誤處理的最佳實踐是什麼?

open FILE, "file.txt" or die $!; 

的處理是在腳本中間die真正處理錯誤的最好方法?

+6

有關perl異常的討論,請參見[有關perl中異常的細節?](http://stackoverflow.com/questions/2165161/whats-broken-about-exceptions-in-perl),[您是否使用Perl程序中的異常類?爲什麼或爲什麼?](http://stackoverflow.com/questions/2439966/do-you-use-an-exception-class-in-your-perl-programs-why-or-why-not)和[在Perl中面向對象的異常處理 - 是否值得?](http://stackoverflow.com/questions/503189/object-oriented-exception-handling-in-perl-is-it-worth-it) – Ether 2010-05-19 22:14:47

回答

21

是否die在腳本中間是否合適取決於您在做什麼。如果只有幾十行,那很好。一個有幾百行的小工具,然後考慮承認(見下文)。如果它是一個大型的面向對象的系統,有很多類和相互關聯的代碼,那麼可能有一個異常對象會更好。

懺悔在Carp包:
常導致模具中的錯誤是不是對死亡的報告線。 用坦白替換模具(參見Carp軟件包)會給堆棧追蹤(我們如何到達這條線),這極大地幫助調試。

爲了處理來自Perl內建函數的異常,我喜歡使用autodie。它從open和其他系統調用中捕獲故障,並且會爲您拋出異常,而不必執行or die位。這些例外情況可以通過eval { }或更好的方式使用Try::Tiny來捕獲。

+4

用於提示'autodie'。 – 2010-05-19 20:57:45

+1

我一直以爲他們應該稱之爲'autoOrDie' :) – friedo 2010-05-20 02:40:40

+0

@friedo它看起來很像'authorDie' :) – dolmen 2014-06-04 16:01:50

3

更現代的方法是使用鯉魚標準庫。

use Carp; 
my $fh; 
open $fh, '<', "file.txt" or confess($!); 

它的主要優點是它給死亡的堆棧跟蹤。

+0

,除非你設置了一些其他的鯉魚東西,否則cro魚不會給出堆棧跟蹤。 – 2010-05-19 20:58:17

+0

@brian:whoop,固定。 – 2010-05-19 20:59:24

+1

謝謝!我不知道鯉魚......但是從什麼時候開始鯉魚呱呱叫? – SystematicFrank 2010-05-19 20:59:41

0

我使用模具,但我把它包裝的eval塊在錯誤處理控制:

my $status = eval 
{ 
    # Some code... 
}; 

如果 'EVAL' 失敗:

  1. $status將是不確定的。
  2. [email protected]將被設置的任何錯誤消息被產生的(或 一個die的內容)

如果「EVAL」成功:

  1. $status將是最後一個返回值塊。
  2. [email protected]將被設置爲''。
+5

'eval {}'有很多問題需要隱晦的解決方法。改用Try :: Tiny。它將所有有害的樣板包裹在乾淨,易於使用的包裝中。 – daotoad 2010-05-19 21:54:24

+1

eval {}'有很多問題需要隱晦的解決方法...如果您關心識別錯誤。如果你打算採取同樣的行動,不管其原因如何,一個簡單的塊'eval'工作正常。但是,是的:在所有其他情況下使用'Try :: Tiny'。 – 2010-05-20 09:40:36

+0

下次我編寫一些Perl時,我會嘗試一下。我使用這種方式來僞造try-catch(通過在eval塊之後添加$ @的檢查。)感謝提示。 – 2010-05-20 14:23:31

12

由於我幾乎在任何地方都使用Log::Log4perl,所以我用$logger->logdie代替die。如果您想對您的例外有更多的控制權,請考慮Exception::Class

最好用Try::Tiny(請參閱它的文檔爲什麼)瞭解您的例外情況。

6

除非你有一個更具體的想法,然後是的當意想不到的事情發生時,你想死。

  • 死亡對未能打開一個文件,並給予文件名是不是系統告訴你它無法讀取或寫入到一個匿名未定義的更好。

  • 如果你正在談論一個「腳本」,一般來說你正在談論一段非常簡單的代碼。不需要協調的層(通常不)。在一個Perl 模塊中,有一個隨之而來的想法是你不擁有執行環境,所以無論是主軟件還是關心它,並且它在eval中捕獲事物,或者它並不真正關心和死亡就沒有問題。然而,你應該嘗試一個更健壯的模塊作爲模塊,並傳回undefs或其他東西。

  • 你可以在eval塊中捕獲任何死亡(或cro)聲)。你可以在那裏做更具體的處理。

  • 但是如果你想檢查$!那麼寫的代碼,你會有一個更具體的決議。

  • 看看使用strict的近似通用標準。這是死於可疑語法的代碼,而不是讓你繼續。

所以我覺得總體思路是:是,DIE,除非你有事情應該如何處理一個更好的主意。如果你有足夠的先見之明,你可以原諒你不會死的一兩次,因爲你知道你不需要。