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

2019-04-08 17:15发布

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?

3条回答
疯言疯语
2楼-- · 2019-04-08 17:37

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)
查看更多
爷、活的狠高调
3楼-- · 2019-04-08 17:41

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

查看更多
倾城 Initia
4楼-- · 2019-04-08 17:43

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

查看更多
登录 后发表回答