Raise

有时你可能希望将异常保持为“活动的”(alive),即使它已被异常处理块捕获。例如,这可用于推迟异常的处理 - 通过将其传递给其他方法。你可以使用 raise 方法执行此操作。但是,你需要注意,一旦异常被抛出(raised),就需要重新处理该异常,否则可能导致程序崩溃。这是一个简单的示例,它引发了一个 ZeroDivisionError 异常,并将异常传递给一个名为 handleError 的方法:

raise.rb
  1. begin
  2. divbyzero
  3. rescue Exception => e
  4. puts( "A problem just occurred. Please wait..." )
  5. x = 0
  6. begin
  7. raise
  8. rescue
  9. handleError( e )
  10. end
  11. end

这里 divbyzero 是一个方法的名称,在该方法中进行除零操作,handleError 是一个打印该异常的更详细的信息的方法:

  1. def handleError( e )
  2. puts( "Error of type: #{e.class}" )
  3. puts( e )
  4. puts( "Here is a backtrace: " )
  5. puts( e.backtrace )
  6. end

请注意,这里使用了 backtrace 方法,该方法显示一个字符串数组 - 显示发生错误所在的文件名和行号,在本例中为调用生成错误的 divbyzero 方法所在的行。

raise2.rb

即使程序代码本身没有引起异常,你也可以专门抛出(raise)异常以强制执行错误条件。单独调用 raise 会抛出 RuntimeError 类型的异常(或全局变量 $! 中的任何异常):

  1. raise # raises RuntimeError

默认情况下,这将没有与之关联的描述性消息。你可以将消息添加为参数,如下所示:

  1. raise "An unknown exception just occurred!"

你可以抛出特定类型的错误…

  1. raise ZeroDivisionError

你还可以创建特定异常类型的对象,并使用自定义消息对其进行初始化…

  1. raise ZeroDivisionError.new( "I'm afraid you divided by Zero" )
raise3.rb

当然,如果标准异常类型不符合你的要求,你可以通过继承现有异常类来创建新的异常类型。为你的类提供 to_str 方法,以便为它们提供默认信息。

  1. class NoNameError < Exception
  2. def to_str
  3. "No Name given!"
  4. end
  5. end

这是一个如何抛出自定义异常的示例:

  1. def sayHello( aName )
  2. begin
  3. if (aName == "") or (aName == nil) then
  4. raise NoNameError
  5. end
  6. rescue Exception => e
  7. puts( e.class )
  8. puts( "message: " + e )
  9. puts( e.backtrace )
  10. else
  11. puts( "Hello #{aName}" )
  12. end
  13. end