• 异常 (Exceptions)

    异常 (Exceptions)

    • 不要把异常用于控制流里 (flow of control)
      [link]

      1. # 错误
      2. begin
      3. n / d
      4. rescue ZeroDivisionError
      5. puts "Cannot divide by 0!"
      6. end
      7. # 正确
      8. if d.zero?
      9. puts "Cannot divide by 0!"
      10. else
      11. n / d
      12. end
    • 避免捕捉 Exception 这个大类的异常
      [link]

      1. # 错误
      2. begin
      3. # an exception occurs here
      4. rescue Exception
      5. # exception handling
      6. end
      7. # 正确
      8. begin
      9. # an exception occurs here
      10. rescue StandardError
      11. # exception handling
      12. end
      13. # 可以接受
      14. begin
      15. # an exception occurs here
      16. rescue
      17. # exception handling
      18. end
    • 传 2 个参数调 raise 异常时不要明确指明RuntimeError。尽量用 error 子类这样比较清晰和明确。[link]

      1. # 错误
      2. raise RuntimeError, 'message'
      3. # 正确一点 - RuntimeError 是默认的
      4. raise 'message'
      5. # 最好
      6. class MyExplicitError < RuntimeError; end
      7. raise MyExplicitError
    • 尽量将异常的类和讯息两个分开作为 raise 的参数,而不是提供异常的实例。[link]

      1. # 错误
      2. raise SomeException.new('message')
      3. # 注意,提供异常的实例没办法做到 `raise SomeException.new('message'), backtrace`.
      4. # 正确
      5. raise SomeException, 'message'
      6. # 可以达到 `raise SomeException, 'message', backtrace`.
    • 避免使用 rescue 的变异形式。
      [link]

      1. # 错误
      2. read_file rescue handle_error($!)
      3. # 正确
      4. begin
      5. read_file
      6. rescue Errno:ENOENT => ex
      7. handle_error(ex)
      8. end