为了账号安全,请及时绑定邮箱和手机立即绑定

[Ruby] 异常捕获

标签:
Ruby


1. 异常类

含有异常信息的数据包是Exception类、或其子类的一个对象。当需要引发异常时,可以使用某个内建的Exception类,或者创建自己的异常类。每个Exception都关联有一个消息字符串和栈回溯信息。如果定义自己的异常,可以添加额外的信息。

当对操作系统的调用返回错误码时,会引发系统错误。Ruby得到这些错误,把每个错误包装到特定对象中,它们都是SystemCallError的子类,定义在Errno模块中,比如Errno::EIO。如果想得到底层的系统错误码,则每个Errno异常对象有一个Errno的类常量,它包含相应的系统错误码,比如Errno::EIO::Errno。

2. 处理异常

在一个begin/end块中,使用一个或多个rescue语句告诉Ruby希望处理的异常类型,例如:

begin

#statement

rescue MyError

  puts $!

raise

end

当异常被引发时,Ruby将相关Exception对象的引用放在全局变量"$!"中。可以不带任何参数来调用raise,它会重新引发"$!"中的异常,它允许我们先编写代码过滤掉一些异常,再把不能处理的异常传递到更高的层次。

在begin块中可以有多个rescue子句,每个rescue子句可以指示捕获多个异常,在rescue子句的结束处,可以提供一个Ruby的局部变量名来接收匹配的异常,例如:

begin

#statement

rescue SyntaxError => boom

  puts boom

rescue StandardError => bang

  puts bang

end

Ruby用引发的异常依次比较begin块中每个rescue子句的每个参数,如果引发的异常匹配了一个参数,Ruby就执行rescue的程序体,同时停止比较。如果编写一个不带参数表的rescue子句,它的默认参数是StandardError,如果没有任何rescue子句与之匹配,或者异常在begin/end块外面被引发,Ruby就沿着调用栈向上查找,在调用者上寻找异常的处理者,接着在调用者的调用者上寻找。

rescue子句的参数通常是Exception类的名称,实际上它们可以是任何返回Exception类的表达式(包括方法调用)。

有时需要保证一些处理在block结束时能够被执行,通过ensure子句可以完成。ensure跟在最后的rescue子句后面,它包含一段当block退出时总是要被执行的代码,不管block是否正常退出,例如:

begin

#statement

rescue SyntaxError => boom

  puts boom

rescue StandardError => bang

  puts bang

ensure

  puts 'end'

end

有时可能可以纠正异常的原因,可以在rescue子句中使用retry语句去重复执行整个begin/end区块,这很可能会导致无限循环。

3. 引发异常

可以使用raise方法在代码中引发异常,例如:

raise

raise "wrong parameters"

raise MyException, "User Define Exception", caller

第一种形式只是简单地重新引发当前异常,如果没有当前异常,则引发RuntimeError。这种形式用于首先截获异常再将其继续传递的异常处理方法中。

第二种形式创建新的RuntimeError异常,把它的消息设置为指定的字符串,然后异常随着调用栈向上引发。

第三种形式使用第一个参数创建异常,然后把相关联的消息设置给第二个参数,同时把栈信息设置给第三个参数。

4. 捕获和抛出

catch和throw能够在正常处理过程期间从一些深度嵌套的结构中跳转出来,例如:

catch (:done) do

  while line = gets

    throw :done unless fields = line.split(/\t/)

  end

end

catch定义了以给定名称为标签的block,这个block会正常执行直到遇到throw为止。当Ruby碰到throw,它回溯调用栈,用匹配的符号寻找catch代码块,当发现它之后,Ruby将栈清退到这个位置并终止该block。

©著作权归作者所有:来自51CTO博客作者尔冬的原创作品,谢绝转载,否则将追究法律责任

Ruby异常捕获编程技术


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消