我有10个Ruby函数调用我想执行,每次调用都可能抛出异常。我想以同样的方式处理每个异常并继续。有没有办法在begin
... rescue
... end
块中包裹每一行?
[编辑]:用例是一个屏幕抓取器/自动化工具,它使用Selenium Web驱动程序填写表单。我不想打扰检查select元素中的选项是否存在,只是尽可能地填写它们。为此,我需要调用Selenium::WebDriver::Support::Select.select_by
并继续,如果它抛出“无法找到值为x的选项”异常。
答案 0 :(得分:6)
我发现this answer也符合我的要求:
def action
yield
rescue
....
ensure
....
end
action { call1 }
action { call2 }
action { call3 }
答案 1 :(得分:5)
你的意思是这样的吗?
class Wtf
def f1
raise "f1"
end
def f2
raise "f2"
end
end
obj= Wtf.new
[:f1, :f2].each do |f|
begin
obj.send f
rescue Exception=> e
p e
end
end
编辑:为示例添加了更多代码
答案 2 :(得分:2)
我喜欢使用#send的qwned方法,但是对于并非所有方法都会按顺序调用的情况,它并不理想。
Continuations非常适合这类事情:
require 'continuation'
class Continuer
# Define five methods for testing
(1..5).each { |i| define_method("method#{i}") { puts "method#{i} called" } }
def do_these_things
cc = nil
callcc { |c| cc = c; method1; }
callcc { |c| cc = c; method2; raise }
# Do other things right here, maybe...
callcc { |c| cc = c; method3; raise }
callcc { |c| cc = c; method4; }
callcc { |c| cc = c; method5; }
rescue
puts 'Caught exception. Continuing.'
cc.call
end
end
Continuer.new.do_these_things
这可以通过在执行每个容易出错的方法时在'cc'变量中记录延续来实现。然后救援声明只是在那个延续时间恢复。它有点像带有动态标签的goto语句。
答案 3 :(得分:0)
你可以这样做:
begin
do_something
do_something_else
do_do_do
rescue Exception1 => e
# error handling
rescue Exception2 => e
# error handling
如果do_something抛出异常,则不会调用其他调用。我认为比做begin.. rescue
块很多更好。只需处理不同的例外情况。
答案 4 :(得分:0)
def f1; raise "X"; end
def f2; raise "Y"; end
#...
funcList = [:f1,:f2,...]
funcList.each{|f|
begin
send(f)
rescue Exception => e
#handle
end
}