inifinity recursion && test/unit

  • Thread starter Andrey Kulinich
  • Start date
A

Andrey Kulinich

Without test/unit ruby finished work and said that stack level too deep.
Is this correct that in this code ruby goes to infinity recursion?

ruby 1.8.0 (2003-06-06) [i386-freebsd4.7]

---
#!/usr/local/bin/ruby
require 'test/unit'

module Recur
def self.new
Recur.new
end
end

class Tests < Test::Unit::TestCase
def test_1
Recur.new
end
end

--
with best regards,
Andrey Kulinich
IT Group
Software developer
phone/fax +380 (372) 58-43-10
e-mail: (e-mail address removed)
http://www.itgrp.net
 
B

Brian Candler

Without test/unit ruby finished work and said that stack level too deep.
Is this correct that in this code ruby goes to infinity recursion?

ruby 1.8.0 (2003-06-06) [i386-freebsd4.7]

---
#!/usr/local/bin/ruby
require 'test/unit'

module Recur
def self.new
Recur.new
end
end

class Tests < Test::Unit::TestCase
def test_1
Recur.new
end
end

Yep, that's definitely a nice piece of infinite recursion. What are you
trying to achieve?

module Recur
def self.new ==> same as def Recur.new

Regards,

Brian.
 
A

Andrey Kulinich

Brian said:
Yep, that's definitely a nice piece of infinite recursion. What are you
trying to achieve?

Originally that was an error. Code:
-
module Recur
def self.new
Recur.new
end

class Recur
end
end

Recur.new
-
But after that I rename class Recur to Another and forgot to change in
def self.new.
Without test/unit ruby said that there is an infinite recursion. Is that
a bug or a feature?
module Recur
def self.new ==> same as def Recur.new

Almost. Depends on position of definition.

--
with best regards,
Andrey Kulinich
IT Group
Software developer
phone/fax +380 (372) 58-43-10
e-mail: (e-mail address removed)
http://www.itgrp.net
 
B

Brian Candler

Originally that was an error. Code:
-
module Recur
def self.new
Recur.new
end

class Recur
end
end

Recur.new

OK, so you have defined:
- a module Recur
- a class Recur::Recur
- a module function Recur::new which calls Recur::Recur.new
(it looks in its own namespace before trying enclosing namespaces,
so Recur::Recur.new is used if it exists; if it doesn't then it will
find Recur.new in the top-level namespace)

So this is not recursive.
But after that I rename class Recur to Another and forgot to change in
def self.new.
Without test/unit ruby said that there is an infinite recursion. Is that
a bug or a feature?

Neither, it's correct behaviour. If class Recur no longer exists, then the
call to 'Recur.new' will refer to the function 'new' in module Recur, which
is itself (hence infinitely recursive).

Regards,

Brian.
 
A

Andrey Kulinich

Brian said:
Neither, it's correct behaviour. If class Recur no longer exists, then the
call to 'Recur.new' will refer to the function 'new' in module Recur, which
is itself (hence infinitely recursive).

I was talking about test/unit.
Why when I'm using it in such code ruby can't detect infinite loop? In
my opinion this is test/unit's bug.

--
with best regards,
Andrey Kulinich
IT Group
Software developer
phone/fax +380 (372) 58-43-10
e-mail: (e-mail address removed)
http://www.itgrp.net
 
B

Brian Candler

I was talking about test/unit.
Why when I'm using it in such code ruby can't detect infinite loop? In
my opinion this is test/unit's bug.

I don't think Ruby really "detects" infinite loops; it simply runs out of
memory and reports it.

When I run your code from RubyTalk:74829 I get:

$ ruby x.rb 2>&1 | head -20
Loaded suite x
Started
..
Error!!!
test_1(Tests):
SystemStackError: stack level too deep
x.rb:6:in `new'
x.rb:6:in `new'
x.rb:6:in `new'
x.rb:6:in `new'
x.rb:6:in `new'
x.rb:6:in `new'
... etc

Now if I strip out the test/unit stuff I get almost exactly the same error:

$ cat x.rb
#!/usr/local/bin/ruby
module Recur
def self.new
Recur.new
end
end

Recur.new

$ ruby x.rb 2>&1
x.rb:4:in `New': stack level too deep (SystemStackError)
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:4:in `New'
... 66668 levels...
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:4:in `New'
from x.rb:8

The only difference seems to be that the error report has this optimisation
of "... 66668 levels..." in there (This is ruby-1.6.8, incidentally)

test/unit traps exceptions, so that
(a) it can count errors, and
(b) it can display errors in the appropriate place (you might be running
with a GTk testrunner, for example)

So I wouldn't expect it to give *exactly* the same output as Ruby's default
exception handler. It does seem pretty close to me though.

If you don't think test/unit is doing the right thing, can you post the
output of running your test program under test/unit, the output when run
without test/unit, and how you think it should be changed?

Regards,

Brian.
 
J

Jason Creighton

I was talking about test/unit.
Why when I'm using it in such code ruby can't detect infinite loop? In
my opinion this is test/unit's bug.

Huh? What do you expect Test::Unit to do? Given this input, with
ruby-1.8.0-preview3 and whatever version of test/unit comes with that:

require 'test/unit'

def recursive()
recursive()
end

class TC_recursive < Test::Unit::TestCase
def test_recursive
recursive()
end
end

....when run, will give this output:

Loaded suite recur
Started
E
Finished in 0.098239 seconds.

1) Error!!!
test_recursive(TC_recursive):
SystemStackError: stack level too deep
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
<snipped several thousand lines of traceback>
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:6:in `recursive'
recur.rb:11:in `test_recursive'
recur.rb:10

1 tests, 0 assertions, 0 failures, 1 errors

What's the problem?

Jason Creighton
 
E

Eric Schwartz

Andrey Kulinich said:
I was talking about test/unit.
Why when I'm using it in such code ruby can't detect infinite loop? In
my opinion this is test/unit's bug.

By definition, a program can't detect whether it'll exit or not
without actually running itself. It's known as the Halting Problem,
and it's a fundamental theorem of Computer Science.

-=Eric
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,173
Latest member
GeraldReund
Top