5

Ruby の再帰関数でのスタック オーバーフロー エラーの回避策はありますか?

たとえば、次のブロックがあるとします。

def countUpTo(current, final)
    puts current
    return nil if current == final
    countUpTo(current+1, final)
end

を呼び出すとcountUpTo(1, 10000)、エラーが発生します: stack level too deep (SystemStackError)

8187 で壊れているようです。Ruby にスタックのサイズを無視するように伝える関数、または最大スタック サイズを増やす方法はありますか?

4

3 に答える 3

2

YARV (Ruby 1.9 の C ベースの実装) を使用している場合は、Ruby VM に末尾呼び出しの最適化をオンにするように指示できます。

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

def countUpTo(current, final)
    puts current
    return nil if current == final
    countUpTo(current+1, final)
end

countUpTo(1, 10_000)
于 2012-01-04T22:26:32.840 に答える
2

Ruby 2.0 では、RUBY_T​​HREAD_VM_STACK_SIZEおよびその他の環境変数を使用して、スタック サイズ (バイト単位) を指定できます。

于 2013-09-05T15:27:16.427 に答える
2

スニペットを再帰的にしないように書き直すことができます。

# 'count_up_to' would be a more "Ruby" name ;-)
def countUpTo(current, final)
  (current..final).each { |i| puts i }
end

あなたのコードはおそらくあなたが実際にやろうとしていることを抽象化したものだと思いますが、再帰的ではなく反復する他の方法を考えれば、解決策を形成するのに役立つかもしれません.

HTH

于 2012-01-04T22:07:56.287 に答える