【问题标题】:How can an exception class obtain the object that raised it?异常类如何获得引发它的对象?
【发布时间】:2013-08-31 04:40:31
【问题描述】:

我希望我的异常类之一能够获取在其上下文中引发异常的对象。例如,在半伪代码中

class Foo
  def zorch!
    raise MyException.new("d'oh!")
  end
end

c = Foo.new
c.zorch!

我希望MyException#initialize能够获得对象c

这可能可以在#initialize 方法中使用self.send(:binding) 以某种方式完成,但我还没有弄清楚如何:

Kernel.eval('self', self.send(:binding)).class.name
=> MyException   # *not* 'Foo'

这是有道理的,因为 MyException 尚未完全实例化,self.send(:binding) 指的是当前上下文而不是调用者的上下文。

那么我如何访问调用者的上下文/绑定?

【问题讨论】:

  • 您找到更好的解决方案了吗?
  • 只是好奇,你为什么需要它?
  • 我相信我想知道这样我就可以将来自异常对象的信息添加到我将要生成的报告中——但我现在完全忘记了。我想念 Digital 的 VMS 功能丰富的异常处理..

标签: ruby exception binding


【解决方案1】:
class MyException < StandardError
  attr_reader :obj
  def initialize obj, *args; super(*args); @obj = obj end
end

class Foo
  def zorch!
    raise MyException.new(self, "d'oh!")
  end
end

c = Foo.new
begin
  c.zorch!
rescue => e
  puts e.obj
end
# => #<Foo:0x007fdd4a474da0>

【讨论】:

  • 不幸的是,我需要为此避免特殊的调用序列,因此更改序列以包含对调用者的引用是行不通的。不过,谢谢。
  • 那么库和 ruby​​ 本身引发的异常呢?
【解决方案2】:

http://docs.honeybadger.io/ruby/exceptions/extending-ruby-exceptions.html 的代码是你能得到的最好的:

require 'binding_of_caller'

module RaiseWithObject
  attr_accessor :exc_obj

  def raise *args
    args.first.exc_obj = self if args.first
    super
  end
end

class Object
  include RaiseWithObject
end

它适用于大多数异常,但不适用于 MRI 内部引发的异常。

【讨论】:

    猜你喜欢
    • 2016-12-03
    • 2015-07-25
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    相关资源
    最近更新 更多