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