0

私はこのようなクラスを持っています:

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

これはうまくいきます。

4

1 に答える 1

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_missingraiseはクラスのメソッドでは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"

あなたが今要点を得たことを願っています。

于 2013-11-12T12:52:24.677 に答える