Ruby中的異常處理代碼編寫示例
單個異常使用 fail 關鍵字僅僅當捕獲一個異常并且反復拋出這個異常(因為這里你不是失敗,而是準確的并且故意拋出一個異常)。
begin fail 'Oops' rescue => error raise if error.message != 'Oops' end
不要為 fail/raise 指定準確的 RuntimeError。
# bad fail RuntimeError, 'message' # good - signals a RuntimeError by default fail 'message'
寧愿提供一個異常類和一條消息作為 fail/raise 的兩個參數(shù),而不是一個異常實例。
# bad fail SomeException.new('message') # Note that there is no way to do `fail SomeException.new('message'), backtrace`. # good fail SomeException, 'message' # Consistent with `fail SomeException, 'message', backtrace`.
不要在 ensure 塊中返回。如果你明確的從 ensure 塊中的某個方法中返回,返回將會優(yōu)于任何拋出的異常,并且盡管沒有異常拋出也會返回。實際上異常將會靜靜的溜走。
def foo begin fail ensure return 'very bad idea' end end
Use implicit begin blocks when possible.如果可能使用隱式 begin 代碼塊。
# bad def foo begin # main logic goes here rescue # failure handling goes here end end # good def foo # main logic goes here rescue # failure handling goes here end
通過 contingency methods 偶然性方法。 (一個由 Avdi Grimm 創(chuàng)造的詞) 來減少 begin 區(qū)塊的使用。
# bad begin something_that_might_fail rescue IOError # handle IOError end begin something_else_that_might_fail rescue IOError # handle IOError end # good def with_io_error_handling yield rescue IOError # handle IOError end with_io_error_handling { something_that_might_fail } with_io_error_handling { something_else_that_might_fail }
不要抑制異常輸出。
# bad begin # an exception occurs here rescue SomeError # the rescue clause does absolutely nothing end # bad do_something rescue nil
避免使用 rescue 的修飾符形式。
# bad - this catches exceptions of StandardError class and its descendant classes read_file rescue handle_error($!) # good - this catches only the exceptions of Errno::ENOENT class and its descendant classes def foo read_file rescue Errno::ENOENT => ex handle_error(ex) end
不要用異常來控制流。
# bad begin n / d rescue ZeroDivisionError puts "Cannot divide by 0!" end # good if d.zero? puts "Cannot divide by 0!" else n / d end
應該總是避免攔截(最頂級的) Exception 異常類。這里(ruby自身)將會捕獲信號并且調(diào)用 exit,需要你使用 kill -9 殺掉進程。
# bad begin # calls to exit and kill signals will be caught (except kill -9) exit rescue Exception puts "you didn't really want to exit, right?" # exception handling end # good begin # a blind rescue rescues from StandardError, not Exception as many # programmers assume. rescue => e # exception handling end # also good begin # an exception occurs here rescue StandardError => e # exception handling end
將更具體的異常放在救援(rescue)鏈的上方,否則他們將不會被救援。
# bad begin # some code rescue Exception => e # some handling rescue StandardError => e # some handling end # good begin # some code rescue StandardError => e # some handling rescue Exception => e # some handling end
在 ensure 區(qū)塊中釋放你程式獲得的外部資源。
f = File.open('testfile') begin # .. process rescue # .. handle error ensure f.close unless f.nil? end
除非必要, 盡可能使用 Ruby 標準庫中異常類,而不是引入一個新的異常類。(而不是派生自己的異常類)
相關文章
Ruby中使用連續(xù)體Continuation實現(xiàn)生成器
這篇文章主要介紹了Ruby中使用連續(xù)體Continuation實現(xiàn)生成器,本文先是介紹了生成器的概念,然后給出實現(xiàn)代碼,需要的朋友可以參考下2015-01-01Ruby rails 頁面跳轉(zhuǎn)(render和redirect_to)
今天在做R.R.log的時候發(fā)現(xiàn)個問題,在修改密碼的時候如果沒有通過校驗,沒有顯示校驗錯誤的信息。2009-05-05ruby線程實現(xiàn)生產(chǎn)者消費者問題示例(隊列Queue實現(xiàn)線程同步)
這篇文章主要介紹了ruby線程實現(xiàn)生產(chǎn)者消費者問題示例(隊列Queue實現(xiàn)線程同步),需要的朋友可以參考下2014-05-05Ruby中使用Block、Proc、lambda實現(xiàn)閉包
這篇文章主要介紹了Ruby中使用Block、Proc、lambda實現(xiàn)閉包,在編程領域我們可以通俗的說:子函數(shù)可以使用父函數(shù)中的局部變量,這種行為就叫做閉包,需要的朋友可以參考下2014-06-06