kenlistian

勤学多思

  IT博客 :: 首页 :: 新随笔 ::  :: 聚合  :: 管理 ::
  207 随笔 :: 0 文章 :: 23 评论 :: 0 Trackbacks

很搞笑,当在搜狗中输入ruby是,其中文是"如碧玉",呵呵,的确是如碧玉啊。闲话少讲,对异常处理做一个总结性笔记。

异常处理的格式如下:

begin
表达式..
[rescue [error_type,..] [=> evar] [then]
表达式..]..
[else
表达式..]
[ensure
表达式..]
end

和c++异常处理是一样的,细节部分不再啰嗦。

1.rescue可以多次重复,

2.当rescue后什么也不带,则为standarError类型异常。

异常类的总类是Exception

其中方法有:backtrace,exception, to_s(to_str),set_backtrace

继承于Exception的异常类有

Interrupt

NotImplementError

SignalException

StandardError 如果在rescure没有指定异常类,则默认异常为该类。

SystemExit

fatal

下面是继承StandardError类中的异常类

1.ArgumentError 参数异常

2.FloatDomainError

3.IndexError

4.IOError 有子类EOFError

5.LoadError

6.LocalJumpError

7.NameError

8 RuntimeError 由raise 引起的错误,

9 SecurityError

10 SyntaxError

11 SystemCallError 有子类Error

12 SystemStackError

13 TypeError

14 ThreadError

15 ZeroDivisionError

在resure中没有指定异常类的话,则默认为StandarError类的错误,则能扑捉到15类的错误类。

采用自定义异常类,则必定继承于StandarError类或其子类。否则不能被resure扑捉到。当然再加个

else也是可以让它处理的,只是这样用法比较少见。

自定义异常类

1.class MyException < RuntimeError
2.end

3.begin
4. raise MyException, "kenlistian example "

5.rescue MyException => myex
6. p myex.to_s
7. p myex.backtrace.join("\n")

8.rescue =>myAllEx

9. p myAllEx.backtrace #处理其他所有的异常。注意,当执行了MyException后,此异常不处理的。同C++

10.end

---------- ruby ----------
"kenlistian example"
"test10.rb:8"

这里说明下backtrace,这个是记录跟踪信息。格式返回的事一个array,如对以上不采用to_s 和join,则返回的是:

---------- ruby ----------
#<MyException: kenlistian example>
["test10.rb:8"]

在backtrace中其中的格式是:

"#{sourcefile}:#{sourceline}:in `#{method}'" (within methods)
"#{sourcefile}:#{sourceline}" (at top level)

再说明下全局变量$#和$@也保存者异常处理的信息。

$# ======> myex 等同抛出的异常对象

$@ ======> myex.backtrace 等同backtrac中处理信息

***********************************

抛出异常,显然用raise。raise不是保留字,是Kernel模块中定义的方法。和fail是同一个格式,格式如下

raise([error_type,][message][,traceback])

如下:

raise
raise message 或 exception
raise error_type, message
raise error_type, message, traceback

第一句将再次引发上一个异常。

第二句,若参数是字符串的话,就把它当作错误信息(message)再引发RuntimeError异常。
若参数为异常对象则引发该异常。

第三句,将引发第一个参数所指的异常,并以第二个参数的内容作为错误信息。

第四句,第三参数装载的是源自于$@或caller的堆栈信息,它指明发生异常的地点。

使用rescue error_type => var就可以得到异常对象。

关于caller方法的说明:

caller([level]) Returns the context information (the backtrace) of current call in the form used for the variable $@. When level specified, caller goes up to calling frames level times and returns the context information. caller returns an empty array at toplevel.

The lines below prints stack frame:

for c in caller(0)
print c, "\n"
end

简而言之,就是察看堆栈信息。其参数表示察看深度。拿例子说话:

def meth1(deep)

meth2(deep)

end

def meth2(deep)

meth3(deep)

end

def meth3(deep)

caller(deep) #察看堆栈信息,deep表示深度

end

puts meth1(0) #0 表示最深,

puts meth1(1) # 察看堆栈中n-1层,就是最后压栈的不看。如下运行结果

---------- ruby ----------
test1.rb:10:in `meth3'
test1.rb:6:in `meth2'
test1.rb:2:in `meth1'
test1.rb:13

test1.rb:6:in `meth2'
test1.rb:2:in `meth1'
test1.rb:13

输出完成 (耗时 0 秒) - 正常终止

******************************************

catch 和throw,这2个方法很自由,主要感觉是独立性很强。你可以在任何地方写一个方法,

然后用catch来扑捉throw,注意别把raise和throw搞错了,catch是不抓raise的。

def method1(n)
puts "come on,kenlistian"
throw :done if n <= 0
puts "go here ,kenlistian"
end

catch(:done) {
method1(-1)
puts 'go here'
}
puts "Reach here!"

---------- ruby ----------
come on,kenlistian
Reach here!

posted on 2008-03-25 13:14 kenlistian 阅读(1484) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。