2013-10-29 33 views
11

Perl當前實現了$SIG{__DIE__},它可以捕獲發生的任何錯誤,即使在eval塊內部也是如此。這有一個非常有用的屬性,您可以在錯誤發生的確切點停止代碼,收集實際錯誤的堆棧跟蹤,將其包含在對象中,然後使用此對象作爲參數手動調用die。在Perl中捕獲運行時錯誤並將其轉換爲例外

此次濫用$SIG{__DIE__}已棄用。正式的,你應該用*CORE::GLOBAL::die代替$SIG{__DIE__}。但是,這兩個是不是遠程等效。 *CORE::GLOBAL::die不是發生運行時錯誤時調用!它所做的只是將明確的呼叫替換爲die()

我不想取代死亡。

我特別感興趣的是捕捉運行時錯誤。

我需要確保在任何模塊的任何深度任何函數中的任何運行時錯誤都會導致Perl將控制權交給我,以便我可以收集堆棧跟蹤並重新拋出。這需要在一個eval塊內部工作 - 一個或多個封閉的eval塊可能需要捕獲異常,但運行時錯誤可能在函數中,而不在任何模塊內部的任何地方包圍eval。

$SIG{__DIE__}完美地支持了這一點,並且忠實地爲我服務了幾年甚至更長的時間 - 但Be™的Powers警告說,這個夢幻般的設施可能會在任何時候被搶走,我不想要一個討厭的驚喜一天下來。理想情況下,對於Perl本身,它們可以爲此創建一個新信號$SIG{__RTMERR__}(對於我來說,切換信號非常簡單,因爲它只能在一個地方掛鉤)。不幸的是,我的說服力不會導致酒鬼打開瓶子,所以假設這種情況不會發生,人們究竟應該如何實現這個目標,以便乾淨地捕捉運行時錯誤?

(例如,這裏另一個答案建議鯉魚::始終,這也...鉤死!)

回答

3

只要做到這一點。我已經完成了。可能每個意識到這個鉤子的人都已經做到了。

這是Perl;幾十年前它仍然是兼容的。我在這裏解釋「已棄用」的意思是「如果你不需要,請不要使用它,總之,」。但是你確實需要它,並且似乎理解了這些影響,所以我會去做。我嚴重懷疑不可替代的語言功能很快就會消失。

並在CPAN上發佈您的工作,因此下一個開發人員不需要再次重新創建此工作。 :)

+0

它已被棄用多年,但到目前爲止,沒有更換已被陳述。這或者意味着它不被棄用,或者他們不打算保留這些功能,或者他們只是忽略說明正確的方法。如果這是實現某些目標的唯一方法,那麼您不能貶低重要的東西!也許他們不會... –

+3

根據[對grep.cpan.me的搜索](http://grep.cpan.me/?q=__DIE__ [%27%22]%3F \} + *%3D )「超過1000個發行版」使用'$ SIG {__ DIE __}'。我認爲它永遠不會去... –