I’d like to be able to write a program that, halfway through
execution, stops what it’s doing and opens an irb session with the
current state. This would be an excellent tool for debugging.
Does anyone know if it’s possible? My instinct says it’s probably
not. If that’s the case, I’d like to if some modification to Ruby
could make it possible, to feed into a potential RCR.
I’d like to be able to write a program that, halfway through
execution, stops what it’s doing and opens an irb session with the
current state. This would be an excellent tool for debugging.
Does anyone know if it’s possible? My instinct says it’s probably
not. If that’s the case, I’d like to if some modification to Ruby
could make it possible, to feed into a potential RCR.
New scope, of course, but still running same program. I don’t know
that there’s any way to get local variables involved, except maybe
grabbing the binding directly.
~ > cat a.rb
require ‘irb’
a, b = 4, 2
begin
c = 42
syntax_error
rescue Exception => e
IRB.setup nil
IRB::Irb.new(IRB::WorkSpace.new(binding),nil).eval_input
end
i confess i have no idea how this works, but it seems to… you need to type
ctrl-D to get out (end STDIN), i’m not sure how to get back into the program…
perhaps someone else could figure it out…
a shorthand for this would be immensely useful - something like
ret = IRB.debug
…
-a
···
On Tue, 4 May 2004, Gavin Sinclair wrote:
I’d like to be able to write a program that, halfway through
execution, stops what it’s doing and opens an irb session with the
current state. This would be an excellent tool for debugging.
Does anyone know if it’s possible? My instinct says it’s probably
not. If that’s the case, I’d like to if some modification to Ruby
could make it possible, to feed into a potential RCR.
Cheers,
Gavin
–
EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================
I’d like to be able to write a program that, halfway through
execution, stops what it’s doing and opens an irb session with the
current state. This would be an excellent tool for debugging.
Does anyone know if it’s possible? My instinct says it’s probably
not. If that’s the case, I’d like to if some modification to Ruby
could make it possible, to feed into a potential RCR.
New scope, of course, but still running same program. I don’t know
that there’s any way to get local variables involved, except maybe
grabbing the binding directly.
The program could provide a callback in some global var that presents all
interesting infos. Of course, locals were still not (directly)
accessible, but one could hack something together using set_trace_func.
Otherwise it might be better to use the debugger anyway…
require ‘irb’
a, b = 4, 2
begin
c = 42
syntax_error
rescue Exception =>> e
IRB.setup nil
IRB::Irb.new(IRB::WorkSpace.new(binding),nil).eval_input
end
~ >> ruby a.rb
irb(main):001:0>> p a,b,c
4
2
42
=>> nil
i confess i have no idea how this works, but it seems to… you need to type
ctrl-D to get out (end STDIN), i’m not sure how to get back into the program…
perhaps someone else could figure it out…
a shorthand for this would be immensely useful - something like
ret = IRB.debug
Well, that’s a good start. Getting back to the program would be
handy.
Then calling IRB.debug is like using a debugger, except the
breakpoints are in the code, which I think is a good thing to be able
to do.
Gavin
···
On Wednesday, May 5, 2004, 12:03:56 AM, Ara.T.Howard wrote:
I’d like to be able to write a program that, halfway through
execution, stops what it’s doing and opens an irb session with the
current state. This would be an excellent tool for debugging.
Does anyone know if it’s possible? My instinct says it’s probably
not. If that’s the case, I’d like to if some modification to Ruby
could make it possible, to feed into a potential RCR.
New scope, of course, but still running same program. I don’t know
that there’s any way to get local variables involved, except maybe
grabbing the binding directly.
It would be cool if you could pass in the current binding to IRB.start.
Is that possible?
This is what I use to break from a program into an irb shell. I set my
app’s interrupt handler to call it, and then reset the interrupt handler
when it is done (where noted). You can go back and forth between app and
shell with ^C and ^D. I usually add some methods to the object that gets
passed to start_session: #help, #commands, methods to pipe data to
gnuplot, etc.
Ara’s idea to pass a binding to Workspace.new is great. Changes to
locals are even persistent after you leave the shell. I’m puzzled about
why that works–maybe irb detects that the object is a binding?
···
–
#!/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(object)
unless $irb
IRB.setup nil
## maybe set some opts here, as in parse_opts in irb/init.rb?
end
workspace = WorkSpace.new(object)
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 current binding"
IRB.start_session(binding)
puts "\nExited irb shell"
p x
end
Ara’s idea to pass a binding to Workspace.new is great. Changes to
locals are even persistent after you leave the shell. I’m puzzled about
why that works–maybe irb detects that the object is a binding?
Yes, that’s what irb does. In irb/workspace.irb:
module IRB
class WorkSpace
# create new workspace. set self to main if specified, otherwise
# inherit main from TOPLEVEL_BINDING.
def initialize(*main)
if main[0].kind_of?(Binding) @binding = main.shift
So you can get two useful effects with WorkSpace.new:
WorkSpace.new(obj)
Makes obj the self of a new workspace.
WorkSpace.new(b, obj)
Makes obj the self of a new workspace, and uses b as the binding.