我喜欢 qwned 的 #send 方法,但对于并非所有方法都将按顺序调用的情况,它并不理想。
延续非常适合这种事情:
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 语句。