В 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 существовать.
Спасибо.