Is there a workaround for “stack level too deep” e

2019-04-08 17:06发布

问题:

Is there any workaround for Stack Overflow errors in recursive functions in Ruby?

Say, for example, I have this block:

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

if I call countUpTo(1, 10000), I get an error: stack level too deep (SystemStackError).

It appears to break at 8187. Is there some function that I can call telling Ruby to ignore the size of stacks, or a way to increase the maximum stack size?

回答1:

If you're using YARV (the C based implementation of Ruby 1.9), you can tell the Ruby VM to turn tail call optimization on:

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)


回答2:

You can rewrite your snippet not to be recursive:

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

I appreciate your code is probably an abstraction of what you're really trying to do, but it might help to form your solution if you think of other ways to iterate rather than recursively.

HTH



回答3:

In Ruby 2.0 you can specify the stack size (in bytes) using RUBY_THREAD_VM_STACK_SIZE and other environment variables.