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