class MyClass < BasicObject
class Error < ::NoMethodError
def method_missing(....)
raise Error
end
end
end
p MyClass.superclass # => BasicObject
p method(:raise).owner # => Kernel
现在Kernel
不存在于MyClass
类的祖先链中。这样当你raise
在方法内部调用时method_missing
,又会再次调用method_missing
方法(因为raise
不是类的方法MyClass
,也不是所有者Kernel
混入Myclass
,所以raise
方法查找失败,导致重复调用method_missing
。因此导致错误为SystemStackError: stack level too deep
。我在这里尝试重新创建您所面临的场景,如下所示:
class Foo < BasicObject
def method_missing(name,*args)
p "hi"
end
end
Foo.new.baz
# stack level too deep (SystemStackError)
这里也是同理。没有Foo#baz
方法,所以method_missing
叫第一次。现在在里面method_missing
,我试图调用另一种方法,即类方法Kernel
。现在Kernel
既不混BasicObject
,也不混Foo
。所以方法查找失败,method_missing
由于调用方法而重复调用Kernel#p
,导致错误。要解决此问题,我将执行以下操作:
class Foo < BasicObject
include ::Kernel
def method_missing(name,*args)
p "hi"
end
end
Foo.new.baz # => "hi"
希望你现在明白了。