Rubyの再帰を「妨害」して、Rubyメソッドが再帰に関与する機能を無効にするにはどうすればよいですか?
ラムダ計算を教えるプログラムの作成に必要ですが、Ruby を使用します。
JavaScript によるクロックフォードの動機 - https://www.youtube.com/watch?v=ya4UHuXNygM&feature=youtu.be&t=1h9m53s
Rubyの再帰を「妨害」して、Rubyメソッドが再帰に関与する機能を無効にするにはどうすればよいですか?
ラムダ計算を教えるプログラムの作成に必要ですが、Ruby を使用します。
JavaScript によるクロックフォードの動機 - https://www.youtube.com/watch?v=ya4UHuXNygM&feature=youtu.be&t=1h9m53s
API を使用して、TracePoint
すべてのメソッドの呼び出しと戻りをトレースし、スタックを構築して、呼び出されたメソッドが既にスタックにあるかどうかを確認できます。そうすれば、少なくとも再帰を検出raise
でき、例外またはexit
プログラムだけを検出できます。
何かのようなもの:
stack = []
TracePoint.trace(:call, :return) do |trace|
p trace, stack
method = trace.method_id
case trace.event
when :call
if stack.include?(method)
$stderr.puts "RECURSION DETECTED: method `#{stack.last}` calls method `#{method}`."
exit!
end
stack.push(method)
when :return
stack.pop
end
end
def foo; bar end
def bar; baz end
def baz; qux end
def qux; bar end
foo
どのように機能するかを観察できるように、そこにデバッグp
rintを貼り付けたことに注意してください。
#<TracePoint:call `foo'@./test.rb:20>
[]
#<TracePoint:call `bar'@./test.rb:21>
[:foo]
#<TracePoint:call `baz'@./test.rb:22>
[:foo, :bar]
#<TracePoint:call `qux'@./test.rb:23>
[:foo, :bar, :baz]
#<TracePoint:call `bar'@./test.rb:21>
[:foo, :bar, :baz, :qux]
RECURSION DETECTED: method `qux` calls method `bar`.