博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Ruby] 异常捕获
阅读量:6259 次
发布时间:2019-06-22

本文共 1792 字,大约阅读时间需要 5 分钟。

1. 异常类

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

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

2. 处理异常

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

begin#statementrescue MyError  puts $!raiseend

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

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

begin#statementrescue SyntaxError => boom  puts boomrescue StandardError => bang  puts bangend

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

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

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

begin#statementrescue SyntaxError => boom  puts boomrescue StandardError => bang  puts bangensure  puts 'end'end

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

3. 引发异常

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

raiseraise "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/)  endend

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

转载地址:http://uuqsa.baihongyu.com/

你可能感兴趣的文章
可能是最好的正则表达式的教程笔记了吧...
查看>>
实战react技术栈+express前后端博客项目(5)-- 前后端实现登录功能
查看>>
MySQL 前缀索引——让索引减负狂奔
查看>>
程序开发者,为什么要和聪明人一起工作?
查看>>
chrome使用技巧(看了定不让你失望)
查看>>
LSAnimator - 易于读写的多链式动画框架
查看>>
有赞透明多级缓存解决方案(TMC)
查看>>
Kotlin:娶妻当娶贤,嫁夫则嫁能
查看>>
设计模式初探之建造者模式(Builder)
查看>>
菜鸟学网络之 —— 长连接和短连接
查看>>
DDFE 技术周刊(第十八期)2017.3.14
查看>>
安得广厦千万间,大赚天下寒士俱欢颜
查看>>
这是一份优美的信息图,吴恩达点赞的deeplearning.ai课程总结
查看>>
去中心化并不是比特币的关键和核心,真的有用才是
查看>>
0629 - 基本完成 iPaste 的 Pin 管理
查看>>
经典:头像与昵称描述的位置组合
查看>>
【CSS模块化之路2】webpack中的Local Scope
查看>>
浙江移动容器云基于 Dragonfly 的统一文件分发平台生产实践
查看>>
「每日一瞥
查看>>
java 线程池
查看>>