Save session in irb

Hello!

Okay, I know this one is a little bit strange, but…

Is there a way to save an irb session meaning that a
Ruby app will pop up irb, the user will execute some
commands and exit irb and in the lifetime of the Ruby
app will have the chance to start irb again and continue
from where he/she left?

To decode the above :-), what I am trying to do is to emulate
the PyRun_InteractiveLoop() of the Python C API via Ruby’s
C API.

I can use system() and friends to start irb via C, but the
session is lost every time the user exits which, of course,
is normal.

Any wild hints? :slight_smile:

Regards,

···


University of Athens I bet the human brain
Physics Department is a kludge --Marvin Minsky

Elias Athanasopoulos wrote:

Hello!

Okay, I know this one is a little bit strange, but…

Is there a way to save an irb session meaning that a
Ruby app will pop up irb, the user will execute some
commands and exit irb and in the lifetime of the Ruby
app will have the chance to start irb again and continue
from where he/she left?

To decode the above :-), what I am trying to do is to emulate
the PyRun_InteractiveLoop() of the Python C API via Ruby’s
C API.

I can use system() and friends to start irb via C, but the
session is lost every time the user exits which, of course,
is normal.

Something like the following? If you run this, you get a series of three
irb shells. You can leave each one and proceed to the next by typing ^D
(^Z on windows, IIRC). Try defining a local variable in the second
shell, and leaving it. Then that local is still accessible in the
third shell. The “binding” stuff is only needed if you want the shell
to be able to see locals in the scope in which it was created.

Of course, you don’t need to use global vars… (I use something like
this code as my interrupt handler for simulations, so I can break and
inspect.)

···

#!/usr/bin/env ruby

require ‘irb’
require ‘irb/completion’

module IRB
def IRB.parse_opts
# Don’t touch ARGV, which belongs to the app which called this module.
end

def IRB.start_session(*args)
unless $irb
IRB.setup nil
## maybe set some opts here, as in parse_opts in irb/init.rb?
end

 workspace = WorkSpace.new(*args)

 if @CONF[:SCRIPT] ## normally, set by parse_opts
   $irb = Irb.new(workspace, @CONF[:SCRIPT])
 else
   $irb = Irb.new(workspace)
 end

 @CONF[:IRB_RC].call($irb.context) if @CONF[:IRB_RC]
 @CONF[:MAIN_CONTEXT] = $irb.context

 trap 'INT' do
   $irb.signal_handle
 end

 custom_configuration if defined?(IRB.custom_configuration)

 catch :IRB_EXIT do
   $irb.eval_input
 end

 ## might want to reset your app's interrupt handler here

end
end

class Object
include IRB::ExtendCommandBundle # so that Marshal.dump works
end

if FILE == $0
x = Object.new
puts “\nStarted irb shell for x”
IRB.start_session(x)
puts “\nStarted irb shell for x with current binding”
IRB.start_session(binding, x)
puts “\nRestarted irb shell for x with current binding”
$irb.eval_input
puts “\nExited irb shell”
p x
end