如何知道哪个类引发了NoMethodError?

时间:2011-09-19 15:46:28

标签: ruby

我不想在某个地方引发NoMethodError,但仅针对某个类(例如NilClass)。

实施例

begin
  maybe_nil_maybe_not_nil = nil
  maybe_nil_maybe_not_nil.x
rescure NoMethodError => ex
  raise unless ex.class_which_raised == NilClass
end

我现在基于异常的to_s执行此操作,但是当您不希望它出现在.id,.product和其他内容时,消息会有所不同。最好根据元数据/参数执行此操作。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:4)

使用控制流的异常通常是一个坏主意。如果您调用的方法本身引发了NoMethodError,会发生什么? (它会被你的拯救区吞没)

最好使用respond_to?

raise 'this is bad' if object.nil?

if object.respond_to?(:x)
  object.x
end

答案 1 :(得分:1)

那么,根据你正在做什么以及你对重新开课的感觉,另一种选择是覆盖你班上的method_missing,例如:

class NilClass
  alias method_missing old_method_missing
  def method_missing(m_sym, *args, &block)
    old_method_missing m_sym, *args, &block
    log_that_you_had_a_missing_method_call
  end
end

这有点脏,但有时你无法控制方法的所有调用者,如果你正在处理例如图书馆。我会确保添加很多关于为什么你的猴子修补你的课程的评论,因为这里可能出现意想不到的副作用。

我建议,如果可能的话,除非有任何TOCTOU问题,否则请在Matt von Rohr的解决方案之前先了解一下。