Ruby перехватывает NoMethodError и продолжает выполнение с того места, где произошло исключение

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

Спасибо.

6
задан Overclocked 28 January 2012 в 20:07
поделиться