[2014年学习计划之RoR系列] 第二步 – 熟悉Ruby语言 (3/n)
来源:互联网 发布:淘宝商标需要注册吗 编辑:程序博客网 时间:2024/06/08 07:11
Ruby中的异常处理
Ruby预定义了常见的异常类型,如下图所示:
所有的异常类都从基类Exception派生出来,这一点跟Java, C#, Python都是类似的。
Ruby特别点的地方 - 当有异常发生时,ruby会将与这个异常相关联的的异常对象放到全局变量$!中去。(这段有点不那么清晰,理解中。。。附上原文吧)
When an exception is raised, and independent of any subsequent exception handling, Ruby places a reference to the associated Exception object into the global variable $!(The exclamation point presumably mirroring our surprise that any of our code could cause errors).
异常处理的例子:
begin
eval string
rescue SyntaxError, NameError => boom
print "String doesn't compile: " + boom
rescue StandardError => bang
print "Error running script: " + bang
end
Ruby使用的是rescue关键字过滤异常,不同于其他语言中常见的catch。在begin块中可以有多个rescue,而且每个rescue可以有多个异常类型。
如果rescue后边没有类型参数,那么Ruby使用StandardError作为缺省值。
系统错误
在POSIX系统上,errno是一个事实上的标准。系统或应用程序都使用errno来报告错误。Ruby将这些错误包装成异常,这些异常类都是派生自SystemCallError。我们可以从类名上看出它们,例如Errno::EIO, Errno::EGAAIN等等。
这些类的Errno字段可以一一对应系统的errno值。
Errno::EAGAIN::Errno35Errno::EPERM::Errno1Errno::EIO::Errno5Errno::EWOULDBLOCK::Errno35
有了try/catch,那么有没有finally?
这个可以有。ensure就是我们要的东西。很直白,就不说了吧。
f = File.open("testfile")
begin
# .. process
rescue
# .. handle error
ensure
f.close unless f.nil?
end
再来看点特别的东西 – else
f = File.open("testfile")
begin
# .. process
rescue
# .. handle error
else
puts "Congratulations no errors!"
ensure
f.close unless f.nil?
end
rescue后面的else子句会在没有异常抛出的时候被执行到。- 好像这个真没什么用啊。
下面上点有用的耍耍。
@esmtp = true
begin
# First try an extended login. If it fails because the
# server doesn't support it, fall back to a normal login
if @esmtp then
@command.ehlo(helodom)
else
@command.helo(helodom)
end
rescue ProtocolError
if @esmtp then
@esmtp = false
retry
else
raise
end
end
有意思的地方就是那个红色加粗的retry。上面这段代码先将esmtp设置为true试着登陆,如果不成功就置为false重试。嗯,我觉得还是挺有用的。
说完了怎么捕获异常,下面该轮到抛出异常了
raise
raise "bad mp3 encoding"
raise InterfaceException, "Keyboard failure", caller
这里的raise实际上是Kernel.raise方法。
第一个raise没有带任何参数,它用来将当前的异常再向外层抛出。如果当前没有异常,那么将会抛出一个RuntimeError。
第二个raise带有一个字符串参数,这个参数被用来构造一个RuntimeError的异常,然后被抛出。
第三个raise带有3个参数,第一个是异常类型,第二个是异常的消息,第三个是call stack。Kernel.caller用来产生调用堆栈。
Ruby中真真儿的catch/throw是这样用滴
当有错误发生的时候,如何从层层负责逻辑中跳出来?C-style longjump? No, Ruby提供了catch/throw的方便用法。
catch (:done) do
while line = gets
throw :done unless fields = line.split(/\t/)
songlist.add(Song.new(*fields))
end
songlist.play
end
catch在这里定义了一个名字为done的代码块,这个代码块正常执行直到遇到异常或正常结束。
又一个例子:
def prompt_and_get(prompt)
print prompt
res = readline.chomp
throw :quit_requested if res == "!"
res
end
catch :quit_requested do
name = prompt_and_get("Name: ")
age = prompt_and_get("Age: ")
sex = prompt_and_get("Sex: ")
# ..
# process information
end
春节前的ruby笔记就到这里了。祝大家马上有钱,马上有房,马上有对象。
- [2014年学习计划之RoR系列] 第二步 – 熟悉Ruby语言 (3/n)
- [2014年学习计划之RoR系列] 第二步 - 熟悉Ruby语言 (1/n)
- [2014年学习计划之RoR系列] 第二步 – 熟悉Ruby语言 (2/n) Blocks and Iterators (代码块和迭代器)
- [2014年学习计划之RoR系列] 第一步 - 搭建开发环境
- Ruby系列文章之3 --- Ruby介绍
- Ruby系列文章之1---开发者应该熟悉的10个工具
- Ruby on Rails(ROR)
- 配置Ruby & ROR
- 2017年第二学期学习计划
- 未来N年的学习计划
- Ruby语言学习系列--ruby基础语法
- 【熟悉引擎第四步】Cocos2d-x 常用控件之Sprite
- 【第二步】编程语言的学习
- Ruby官方网站换装,基于ROR
- RoR(Ruby on Rails)????
- Ruby或ROR学习第一步
- 边学边做ROR(安装ruby-debug)
- [转]Ruby on Rails (ROR)
- killer of screen - tmux
- Ubuntu安装Networkx
- 配置文件解析库 myconf 使用wiki
- Fragment中 onActivityResult不响应 + 有关onActivityResult提前调用的问题
- 【Linux】关机设置,与BT5IP设置
- [2014年学习计划之RoR系列] 第二步 – 熟悉Ruby语言 (3/n)
- 一切成功源于积累——20140128 再次损失1300多美金
- 数学建模小议(第0章)
- 各种常用的JSON接口,天气,手机归属地,IP地理位置,QQ空间,优酷,微博,等
- 从3DS MAX建模到Ogre实时动画的制作过程
- 快速恢复Safengine Protector的Shadow DLL
- 当春晚晋升国家级项目
- iphone开发之——自动适应键盘的高度
- 记录#pragma pack()的问题