Brad Werth
Brad Werth

Reputation: 17647

Is it possible to create "SystemStackError: stack level too deep" errors without recursion?

Consider the following irb interaction:

2.1.1 :001 > def do_it
2.1.1 :002?>   do_it
2.1.1 :003?> end
 => :do_it 
2.1.1 :004 > do_it
SystemStackError: stack level too deep

In this example, does it detect the certainty of running out of stack or does it actually run out of stack? Is it possible to produce this error without using recursion?

Upvotes: 1

Views: 94

Answers (3)

Jordan Running
Jordan Running

Reputation: 106037

In this example, does it detect the certainty of running out of stack or does it actually run out of stack?

It actually runs out of stack. It is, in fact, impossible to "detect the certainty of running out of stack" in the general case because of the halting problem, one of the core problems in computer science.

Is it possible to produce this error without using recursion?

Sure. Just define a lot of methods, each of which calls the next:

20000.times do |n|
  define_method :"foo_#{n}" do
    puts "Called #{__method__}"
    send :"foo_#{n+1}"
  end
end

foo_0
# -> Called foo_0
# -> Called foo_1
# -> Called foo_2
# -> Called foo_3
# ...
# -> Called foo_4931
# -> SystemStackError: stack level too deep

Upvotes: 3

Cam
Cam

Reputation: 931

It does actually reach its maximum stack limit...

def do_it x=1
  puts "Do it #{x}"
  do_it x+1
end
do_it

Here's a reasonable explanation of Ruby's stack limitations: How to increase stack size for a ruby app. Recursive app getting: Stack level too deep (SystemStackError)


Summary of Ruby stack details

courtesy @gregspurrier:

  • v1.8.x used C stack
  • v1.9.x used virtual memory with its own stack
  • v2.0.0 this VM limit can be set via RUBY_THREAD_VM_STACK_SIZE

Upvotes: 2

Pascal
Pascal

Reputation: 8646

It actually runs out of space on the stack. Every method invocation needs some space on the stack. You could have code like this:

def method_1
  method_2
end
def method_2
  method_3
end
...
...
def method_123456
  method_123457
end

method_1

There is no recursion involved but still it will run out of stack space at some point.

Upvotes: 1

Related Questions