2009-04-30 196 views
3

我會通過編程的Ruby的書,我有問題的理解以下概念:Ruby的異常處理問題

  1. 作者談論的代碼中可能出現的「暫時性異常」,然後提出一個創建自己的異常對象來處理它們。我不認爲我完全理解什麼是瞬態錯誤,何時適合製作自己的Exception對象。他Chapter 6談到它時,他談到定義例外:

例如,某些類型的網絡錯誤可能是短暫的。 第6章第97頁。將信息添加到例外。

  • 我還具有一個很難得到圍繞捕捉的使用,並且在紅寶石投擲。什麼時候比籌集和拯救更好?
  • 回答

    11

    你能給我們提供一個頁面引用「暫時性例外」一行嗎?

    無論如何,您可以隨時創建一個新的異常,通常這樣做可以讓您傳輸更多關於故障的信息。當你有低級別異常並且希望將其變成對用戶更有意義的東西時,這是特別好的。

    Ruby中的拋出/捕獲實際上是一種非局部轉換,像C中的setjmp/longjmp一樣,但表現更好。只要您想長時間執行轉換,就可以使用它。

    顯然,出於同樣的原因,你不想使用goto很多,你不想這樣做。你可能會使用它的一個重要原因是程序需要保持運行,所以如果你發現某些類型的錯誤,你可能會轉儲你正在做的所有工作,並返回到開始。


    好吧,這似乎並沒有被任鎬頭書我已經得到的版本的97頁上,但我看到的是什麼意思。哦,這是第三版第157頁。

    首先,在關於「瞬態」的業務中,存在一些可能發生的網絡問題,然後自行解決,比如BOFH拔掉網絡電纜並將其插回。因此,在某些情況下,你可能想給它幾秒鐘安頓下來,然後在恐慌之前再試一次。你會怎麼做?

    在這種情況下,他們定義了一種新的異常。這只是繼承完成:

    class RetryException < RuntimeError 
        # so this is a kind of RuntimeError which is a kind of Exception 
        attr: ok_to_retry 
        def initialize(ok_to_retry) 
        @ok_to_retry 
        end 
    end 
    

    這樣的話如果出現錯誤,你可以在這些新的重試例外

    raise RetryException.new(true), "transient read error" 
    

    現在發送的東西,是一種RuntimeError了堆棧的提高,但是現在有附加的信息,即標有「是的,這可以重試」。

    NOw,這裏是真的很漂亮 Ruby中的事情:它具有內置的重試某些事情的能力。所以,在堆疊的某個位置,你有這樣的代碼:

    begin 
        # do something that raises this exception 
        do_something() 
    rescue RetryException => detail 
        # if the exception is one of these retryable ones, 
        # catch it here, but it in detail 
        if detail.ok_to_retry 
         retry 
        end 
        # this means exactly the same as 'retry if detail.ok_to_retry` 
        # from the book, btw 
    
        # if it STILL doesn't work, send the exception on 
        raise # just re-raises the last exception 
    end 
    
    +2

    這個SIR真棒。 – unj2 2009-04-30 06:15:58