很搞笑,当在搜狗中输入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!