我有一个这样的课程:
class MyClass < BasicObject
class Error < ::NoMethodError
end
end
我有这个:
def method_missing(....)
raise Error
end
当我调用丢失的方法时,我得到SystemStackError: stack level too deep
。我想有些递归正在进行,但我不明白为什么到底以及发生了什么。
你能帮帮我吗?
PS
class MyClass
class Error < NoMethodError
end
end
这很有效。
答案 0 :(得分:2)
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
方法看起来如此up失败,并导致重复调用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"
而重复调用,并导致错误。为了解决这个问题,我将采取以下措施:
{{1}}
希望你现在明白了。