Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a workaround for "stack level too deep" errors in recursive routines?

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?

like image 273
Benjamin Kovach Avatar asked Jan 04 '12 19:01

Benjamin Kovach


3 Answers

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)
like image 167
Andrew Grimm Avatar answered Nov 14 '22 15:11

Andrew Grimm


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

like image 41
Pavling Avatar answered Nov 14 '22 14:11

Pavling


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

like image 2
michau Avatar answered Nov 14 '22 14:11

michau