Ruby Ruby 异常处理的几个细节

tomlk · 2015年09月03日 · 最后由 tomlk 回复于 2015年09月03日 · 2700 次阅读

1,异常发生时被自动赋值的变量

$! 最后发生的异常(异常对象) $@ 最后发生的异常的位置信息

示例:

irb(main):006:0* begin
irb(main):007:1*   abc
irb(main):008:1> rescue
irb(main):009:1>   puts $!.class
irb(main):010:1>   puts $!.inspect
irb(main):011:1>   puts $@.class
irb(main):012:1>   puts $@.inspect
irb(main):013:1> end
NameError
#<NameError: undefined local variable or method `abc' for main:Object>
Array
["(irb):7:in `irb_binding'", "C:/Ruby22/lib/ruby/2.2.0/irb/workspace.rb:86:in `eval'", "C:/Ruby22/lib/ruby/2.2.0/irb/workspace.rb:86:in `evaluate'", "C:/Ruby22/lib/ruby/2.2.0/irb/context.rb:379:in `evaluate'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:489:in `block (2 levels) in eval_input'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:623:in `signal_status'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:486:in `block in eval_in
put'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:245:in `block (2 levels) in each_top_level_statement'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'", "C:/Ruby22/li
b/ruby/2.2.0/irb.rb:485:in `eval_input'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:395:in `block in start'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `catch'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `start'", "C:/Ruby22/bin/irb:11:in `<main>'"]

2,异常对象的方法

class 异常的种类 message 异常信息 backtrace 异常发生的位置信息($@与$!.backtrace 是等价的)

示例:

irb(main):004:0* begin
irb(main):005:1*   abc
irb(main):006:1> rescue => ex
irb(main):007:1>   p ex.class
irb(main):008:1>   p ex.message
irb(main):009:1>   p ex.backtrace
irb(main):010:1> end
NameError
"undefined local variable or method `abc' for main:Object"
["(irb):5:in `irb_binding'", "C:/Ruby22/lib/ruby/2.2.0/irb/workspace.rb:86:in `eval'", "C:/Ruby22/lib/ruby/2.2.0/irb/workspace.rb:86:in `evaluate'", "C:/Ruby22/lib/ruby/2.2.0/irb/context.rb:379:in `evaluate'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:489:in `block (2 levels) in eval_input'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:623:in `signal_status'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:486:in `block in eval_in
put'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:245:in `block (2 levels) in each_top_level_statement'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'", "C:/Ruby22/li
b/ruby/2.2.0/irb.rb:485:in `eval_input'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:395:in `block in start'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `catch'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `start'", "C:/Ruby22/bin/irb:11:in `<main>'"]
=> ["(irb):5:in `irb_binding'", "C:/Ruby22/lib/ruby/2.2.0/irb/workspace.rb:86:in `eval'", "C:/Ruby22/lib/ruby/2.2.0/irb/workspace.rb:86:in `evaluate'", "C:/Ruby22/lib/ruby/2.2.0/irb/context.rb:379:in `evaluate'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:489:in `block (2 levels) in eval_input'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:623:in `signal_status'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:486:in `block in eval
_input'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:245:in `block (2 levels) in each_top_level_statement'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'", "C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'", "C:/Ruby22
/lib/ruby/2.2.0/irb.rb:485:in `eval_input'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:395:in `block in start'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `catch'", "C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `start'", "C:/Ruby22/bin/irb:11:in `<main>'"]

3, ensure,retry 和 rescue

ensure:后处理,ensure 中的处理在程序跳出 begin~end 部分时一定会执行。

retry:重试,在 rescue 中使用 retry 后,begin 以下的操作会再重做一遍。

rescue 修饰符:可以和 if 修饰符一样提高代码简洁性。

表达式 1 rescue 表达式 2

等价于:

begin 表达式 1 rescue 表达式 2 end

示例:

n = Integer(val)  rescue  0 

bactrace, 应该是 backtrace 吧

#1 楼 @chenge 对的~抱歉,我改正下~

需要 登录 后方可回复, 如果你还没有账号请 注册新账号