禁用Ruby中的递归以强制使用Y Combinator

时间:2016-02-19 12:37:29

标签: ruby recursion metaprogramming y-combinator

Ruby的递归如何被破坏'禁用ruby方法进行递归的能力?

需要创建一个教授lambda演算的程序,但需要使用Ruby。

来自Crockford的JavaScript动机 - https://www.youtube.com/watch?v=ya4UHuXNygM&feature=youtu.be&t=1h9m53s

1 个答案:

答案 0 :(得分:2)

您可以使用TracePoint API跟踪所有方法调用并返回并构建堆栈,以查看调用的方法是否已在堆栈中。这样,您至少可以检测递归,然后您只需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`.