Ruby 异常
Ruby 异常
Ruby 异常是一个对象,是 Exception 类的实例或该类的后代。它代表某种特殊情况。
在 Ruby 程序中,当出现问题时,它会引发异常行为。默认情况下,Ruby 程序在抛出异常时终止。
我们可以在 Ruby 中声明一些异常处理程序。异常处理程序是一个代码块,它在其他代码块中发生异常时执行。
异常有两种处理方式。您可以终止程序或处理异常。为了处理异常,您可以提供一个救援子句。通过提供这一点,程序控制流向救援子句。
当引发异常但未处理时,全局变量 $! 包含当前异常和 [email protected] 包含当前异常的回溯。
Ruby 预定义类(如 Exception 及其子类)可帮助您处理程序错误。在 Ruby 异常层次结构中,大多数子类都扩展了 StandardError 类。这些是正常的例外。
Ruby 类异常
异常的内置子类如下:
NoMemoryError
脚本错误
安全错误
信号异常
标准错误
系统退出
系统堆栈错误
致命-无法营救
示例:
def raise_exception puts
'I am before the raise.' raise
'oops! An error has occured' puts
'I am after the raise' end raise_exception
输出:
raise 方法来自 Kernel 模块。
处理异常
为了处理异常,引发异常的代码包含在 begin-end 块中。使用救援子句,我们可以声明我们想要处理的异常类型。
示例:
def raise_and_rescue begin puts
'Before the raise.' raise
'An error occured.' puts
'After the raise.' rescue puts
'Code rescued.' end puts
'After the begin block.' end raise_and_rescue
输出:
在上面的例子中,中断的代码没有完全运行.异常处理代码在begin-end 块之后恢复之后。
如果在rescue 子句中没有定义参数,则参数默认为StandardError。每个救援子句指定多个要捕获的异常。如果不带任何参数使用raise,则可能会重新引发异常。
rescue 子句写在begin/rescue 块中。一个救援子句没有处理的异常将在下一个子句中处理。
begin code.. rescue OneTypeOfException code.. rescue AnotherTypeOfException code.. else
# Other exceptions end
在begin 块中,每个引发异常的rescue 子句将依次与每个参数进行比较。当抛出的错误类型和救援子句中命名的异常类型相同或者是该异常的超类时,它将被匹配。如果 begin 语句的主体无异常地完成,则执行 else 子句。如果发生异常,则不会执行 else 子句。
异常对象
异常对象是普通对象。一个被拯救的异常可以被保留在rescue 子句中的一个变量中。
示例:
begin raise
'an exception' rescue ZeroDivisionError => e puts
"Exception Class: #{ e.class.name }" puts
"Exception Message: #{ e.message }" puts
"Exception Backtrace: #{ e.backtrace }" end
Exception 类定义了两个返回异常详细信息的方法。 message 方法返回一个定义错误解释的字符串。 backtrace 方法返回一个字符串数组,该数组表示引发异常时的调用堆栈。
使用重试语句
通常在救援子句中,异常被捕获并在开始块之后恢复代码。使用 retry 语句,可以在捕获异常后从头开始恢复救援块代码。
语法:
begin code.... rescue
# capture exceptions re
try
# program will run from the begin block end
示例:
#!/usr/bin/ruby begin x = Dir.mkdir
"alreadyExist"
if x puts
"Directory created" end rescue y =
"newDir" re
try end
以上程序运行如下:
步骤1 在begin 块中,编写代码以创建一个已经存在的目录。
第 2 步这将引发错误。
第 3 步在救援块中,y 被重新分配。
步骤 4 重试语句将转到开始块。
步骤 5 将创建目录。
使用 raise 语句
raise 语句用于引发异常。
语法:
或者,
或者,
raise ExceptionType,
"Error Message"
或者,
raise ExceptionType,
"Error Message" condition
第一个重新引发当前异常。它用于异常处理程序,其中异常在传递之前被拦截。
第二个创建一个新的 RuntimeError 异常。然后在调用堆栈中引发此异常。
第三个使用第一个参数创建异常,然后将关联的消息设置为第二个参数。
第四个与第三个类似。在这里,您可以添加任何条件语句来引发异常。
示例:
#!/usr/bin/ruby begin puts
'code before raise.' raise
'exception occurred.' puts
'code after raise.' rescue puts
'I am rescued.' end puts
'code after begin block.'
输出:
使用 ensure 语句
有一个 ensure 子句保证在代码末尾进行一些处理。无论是否引发异常,确保块始终运行。它位于最后一个救援子句之后,并且将始终在块终止时执行。
确保块将在任何情况下运行,无论是异常发生、异常被拯救还是代码被未捕获的异常终止。
语法:
begin code..
#..raise exception rescue
#.. exception is rescued ensure
#.. this code will always execute. end
示例:
begin raise
'Exception' rescue Exception => e puts e.message puts e.backtrace.inspect ensure puts
"The ensure code will always run" end
输出:
使用else 语句
else 子句总是出现在rescue 子句之后和ensure 子句之前。如果没有引发异常,则只执行 else 块。
语法:
begin code..
#..raise exception rescue
# .. exception is rescued else
#.. executes if there is no exception ensure
#.. this code will always execute. end
示例:
begin
# raise 'A test exception.' puts
"no exception is raised" rescue Exception => e puts e.message puts e.backtrace.inspect
else puts
"else code will be executed as no exception is raised." ensure puts
"ensure code will run" end
输出:
Ruby Catch and Throw
Ruby catch and throw 提供了一种在代码中不需要进一步工作时尽早跳出执行的方法。
catch 定义了一个用给定名称标记的块。用于跳出嵌套代码。使用catch,块将正常执行,直到遇到throw。
catch 和throw 方法比rescue 和raise 子句更快。因此,它更适合使用。
语法:
throw :lablename
#.. this code will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered. end
或者,
throw :lablename condition
#.. this code will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered. end
示例:
def promptAndGet(prompt) pr
int prompt res = readline.chomp
throw :quitRequested
if res ==
"!"
return res end
catch :quitRequested
do name = promptAndGet(
"Name: ") age = promptAndGet(
"Occupation: ")
# ..
# process information end promptAndGet(
"Name:")
输出:
