begin
    #可能发生异常的地方
rescue
    #如何处理异常
end

rescue,哈哈,太有爱的一个单词了。。。

begin
    #可能发生异常的地方
rescue => exception
    #如何处理异常
end

这样一来,exception就可以用来存放异常对象了。

$!:用来存放最后一次发生的异常对象

$@:异常发生的位置等信息。

异常对象的方法:

class:例外的类别

message: 例外的消息

backtrace: $@等同于$!.backtrace,异常发生的位置信息

更加完善的异常处理

begin
    #process
rescue => ex
    #process on ex
ensure
    #无论如何都会执行的动作
end

※在ensure中可以使用retry,他会重新去执行begin中的内容,如果没有强制退出则一直执行。

rescue可以像if, unless一样使用如下形式:

n = Integer(val) rescue 0

#跟上面同样的效果
begin
  n = Integer(val)
rescue
  n = 0
end

如果val不是一个数字类型的字符串的话,n就等于0。

按照异常分类处理

begin
    #process
rescue Exception1, Exception2 => ex
    #process on ex
rescue Exception3, Exception4 => ex2
    #process on ex2
rescue => ex3
    #process on other kinds of exceptions
end

StandardError

这个类是Exception的自类,Exception还有其他的子类。但是rescue补救的知识StandardError类或者是其子类。

于是我们设计自己的异常的时候,需要首先继承这个StandardError。

class VoctralsError < StandardError; end

然后,其它的类可以继承这个VoctralsError类。

class Error1 < VoctralsError; end

引发异常raise

raise "Error Information"  #产生一个RuntimeError,"Error Information"作为异常的message;

raise SomeException  #产生一个SomeException

raise SomeException, "Error Information"  #产生一个SomeException,并设定其message为"Error Information"

raise

1)写在rescue之外,直接引发一个RuntimeError;

2)写在rescue内,再次引发导致该rescue发生的异常($!)。

throw和catch

catch(:some){
    #something before a :some throw
    throw :some
    #something after a :some throw
}

catch能够保证:some之前的代码顺利进行,当出现:some被throw之后,后面的代码不会执行。

看起来类似if。

但是可以用这个来打断一个多层循环:

catch(:test){
    loop{
        loop{
          ...
          if val != 0
            throw :test, val
          end
       }
    }    

throw有两个参数的时候,第二个参数作为catch的返回值。

04-30 04:18