Ruby捕获NoMethodError并从发生异常的地方继续执行
发布时间:2020-12-17 03:02:04 所属栏目:百科 来源:网络整理
导读:在 Ruby中,我想捕获在另一个对象中的对象上生成的NoMethodError,然后将一些值返回到引发异常的位置并继续执行.有现成的方法吗? 我想出的最好的是: class Exception attr_accessor :continuationendclass Outer def hello puts "hello" end class Inner def
在
Ruby中,我想捕获在另一个对象中的对象上生成的NoMethodError,然后将一些值返回到引发异常的位置并继续执行.有现成的方法吗?
我想出的最好的是: class Exception attr_accessor :continuation end class Outer def hello puts "hello" end class Inner def world puts "world" end def method_missing(method,*args,&block) x = callcc do |cc| e = RuntimeError.exception(method) e.continuation = cc raise e end return x end end def inner(&block) inner = Inner.new begin inner.instance_eval(&block) rescue => e cc = e.continuation cc.call(hello()) end inner end end o = Outer.new o.inner do hello world end 这打印 hello world 有没有更好的方法来使用Ruby现有的元编程库?基本上,我不确定callcc是否会继续存在. 谢谢. 解决方法
这个简单的方法怎么样:
class Outer def hello puts "hello" end class Inner def initialize outer @outer = outer end def world puts "world" end def method_missing(method,&block) @outer.send(method,&block) rescue NoMethodError # you can also add this puts "#{method} is undefined in both inner and outer classes" end end def inner(&block) inner = Inner.new self inner.instance_eval(&block) inner end end o = Outer.new o.inner do hello cruel world end 会打印 hello cruel is undefined in both inner and outer classes world 在这种情况下,如果内部类没有定义所需的方法,则使用Object#send将其委托给外部类.您可以在method_missing中捕获NoMethodError,以便在外部类未定义委托方法时控制情境. UPDATE class Outer def hello puts "hello" end class Inner def world puts "world" end def method_missing(method,&block) Fiber.yield [method,args,block] # pass method args to outer end end def inner(&block) inner = Inner.new f = Fiber.new { inner.instance_eval(&block) } result = nil # result for first fiber call does not matter,it will be ignored while (undef_method = f.resume result) # pass method execution result to inner result = self.send(undef_method[0],*undef_method[1],&undef_method[2]) end inner end end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |