Resetting ruby

L

List Recv

I'm looking for a fast way to "reset" Ruby. That is, to reset the
interpreter back to a fresh state, or, even better, a fresh state +
keeping some required ruby-gems.

My goal is to make a continuos test runner, and avoid the overhead of
having to restart ruby and require the gems each times.

I could do this with fork (copy-on-write), except I want this to run on
Win32 as well.

Any ideas?
 
L

Logan Capaldo

I'm looking for a fast way to "reset" Ruby. That is, to reset the
interpreter back to a fresh state, or, even better, a fresh state +
keeping some required ruby-gems.

My goal is to make a continuos test runner, and avoid the overhead of
having to restart ruby and require the gems each times.

I could do this with fork (copy-on-write), except I want this to
run on
Win32 as well.

Any ideas?

I'm confused, why do you need to "reset" ruby everytime? Can't you
stick the tests in a loop?
 
L

List Recv

Logan said:
I'm confused, why do you need to "reset" ruby everytime? Can't you
stick the tests in a loop?

The code - and it's require files - are constantly changing. (That's
the whole point of continuos testing!). I want to a) make sure to
reload all required files and b) make sure to start with a fresh slate,
in terms of class definitions, ObjectSpace, and the like.
 
L

Logan Capaldo

The code - and it's require files - are constantly changing. (That's
the whole point of continuos testing!). I want to a) make sure to
reload all required files and b) make sure to start with a fresh
slate,
in terms of class definitions, ObjectSpace, and the like.

Ok, so change the 'require's to 'load's and then stick it in a
loop ;). In seriousness though, all the work involved with undefining
everything, and you might as well just start a new ruby executable.
Perhaps I'm not understanding you correctly, how would you do this
with fork, and avoid the overhead of requiring things?
 
L

List Recv

Logan said:
Ok, so change the 'require's to 'load's and then stick it in a
loop ;). In seriousness though, all the work involved with undefining
everything, and you might as well just start a new ruby executable.
Perhaps I'm not understanding you correctly, how would you do this
with fork, and avoid the overhead of requiring things?

fork would save the overhead of loading ruby itself
 
J

Jacob Fugal

fork would save the overhead of loading ruby itself

However, with fork you'd need to be careful about open filehandles and
the like which are shared between the processes. Getting consistent
results between a stay alive process like this and a new process each
time can be really tricky.

Jacob Fugal
 
L

Logan Capaldo

That's not quite sufficient. 'load' simply loads the file again. It
doesn't replace the result of previously loading the file. So if the
"signature" of the file is the same (all the same classes, methods,
variables, etc. declared only with different values/implementations)
you're good. But in the more frequent case where the signature changes
in a non-additive way (e.g. a method is removed), that change is *not*
propagated by a new load. That means the method that was removed is
still available within the test script, which may cause some tests to
pass which should fail and would fail if run under a new instance.

Jacob Fugal

I know, hence the smiley face. I still think this idea is a little
extreme for the minor savings you'd get out of it.
 
E

Eivind Eklund

I'm looking for a fast way to "reset" Ruby. That is, to reset the
interpreter back to a fresh state, or, even better, a fresh state +
keeping some required ruby-gems.

My goal is to make a continuos test runner, and avoid the overhead of
having to restart ruby and require the gems each times.

I've got code for this kind of testrunner; no specific optimizations,
though. It's a plain testrunner using pipes for communication and a
fork to separate out the execution. There's something clumsy about it
- I don't remember what it was.

If you're dead set on doing this inside a single Ruby process, this
won't help - if you want an easy way out, I'll try to dig up the code
- it wasn't in the obvious places :-/

Eivind.
 
J

John W. Long

List said:
I'm looking for a fast way to "reset" Ruby. That is, to reset the
interpreter back to a fresh state, or, even better, a fresh state +
keeping some required ruby-gems.

My goal is to make a continuous test runner, and avoid the overhead of
having to restart ruby and require the gems each times.

One thing you could do would be to load up all of your libraries and
pause on the terminal waiting for user input. As soon as the user
unpaused the process it would load in the test cases and run them. As
the user was looking at the output and fixing tests you could load up
another instance and pause waiting for user input. Stir and repeat...

I've thought for a long time that something like this would be very
useful for Rails testing where loading up the library code takes 2-3
seconds, making unit testing tedious.
 
L

List Recv

Dalibor said:
The possibility to reset the interpreter would be IMHO useful also for other
situations where you have persistent Ruby processes (think mod_ruby).
I've thought for a long time that something like this would be very
useful for Rails testing where loading up the library code takes 2-3
seconds, making unit testing tedious.

Okay, Ruby core hackers, can you answer our call?!
 
K

Kero

I'm looking for a fast way to "reset" Ruby. That is, to reset the
I've got code for this kind of testrunner; no specific optimizations,
though. It's a plain testrunner using pipes for communication and a
fork to separate out the execution. There's something clumsy about it
- I don't remember what it was.

Well, there's exit! in the code below that I find rather clumsy, but I don't
think that is what you mean. Other than that, would your code look similar?
(code below is an experiment that I put in webrick. yes, I found webricks
cgihandler and it works fine; in theory this should be faster, in practise
the ruby-cgi program that was started was too slow to notice the difference,
which -incidentally- was caused by CGI.new("html4") taking lots of time;
enough of that, let's look at the code).

mm, I forgot to reopen stderr, I see now.


# Run +program+ giving it +input+ over stdin and producing its output as a
# String. The optional +max_time+ is used as a timeout. It is assumed that the
# environment (Ruby's ENV) has been prepared.
def CGI.runner(program, input="", max_time=1.0)
# rd, wr = IO.pipe
parent2child = IO.pipe
child2parent = IO.pipe

if fork
result = ""
parent2child[0].close
child2parent[1].close

parent2child[1].print input
while line = child2parent[0].gets
result << line
end

child2parent[0].close
parent2child[1].close
result
else
begin
parent2child[1].close
child2parent[0].close

$stdin.reopen parent2child[0]
$stdout.reopen child2parent[1]
timeout(max_time) {
load program
} # rescue TimeoutError

child2parent[1].close
parent2child[0].close
ensure
# Do not interfer with the 'real' server stuff (of the parent), whose
# code is running here as well, specifically including closing of the SSL
# socket.
exit!
end
end
end
 
M

Michael Ulm

John said:
I don't think there's a need for Ruby core hacking if you follow my
suggestion:

That would work in this one case where resetting is useful. As this
thread has shown, there are others. Here is mine: I want to use an
irb-like environment in conjunction with gsl as a kind of super
calculator/numerical test engine. A reset method would be tremendously
useful as one often wants to start with a clean slate, without losing
all the output from the previous computations.

So, I second List Recv's plea to the core hackers: ideas anyone?

--
Michael Ulm
R&D Team
ISIS Information Systems Austria
tel: +43 2236 27551-219, fax: +43 2236 21081
e-mail: (e-mail address removed)
Visit our Website: www.isis-papyrus.com
 
J

Joel VanderWerf

Michael said:
That would work in this one case where resetting is useful. As this
thread has shown, there are others. Here is mine: I want to use an
irb-like environment in conjunction with gsl as a kind of super
calculator/numerical test engine. A reset method would be tremendously
useful as one often wants to start with a clean slate, without losing
all the output from the previous computations.

So, I second List Recv's plea to the core hackers: ideas anyone?

Doesn't GC clean the slate well enough for calculations?
 
E

Eric Hodel

I'm looking for a fast way to "reset" Ruby. That is, to reset the
interpreter back to a fresh state, or, even better, a fresh state +
keeping some required ruby-gems.

My goal is to make a continuos test runner, and avoid the overhead of
having to restart ruby and require the gems each times.

In order to ensure your tests won't fail or pass when they should do
the opposite you should start up from a clean interpreter.
 

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

No members online now.

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top