Once I needed to write a Ruby script which dropped the user to an irb prompt, keeping their current context. They’d then be able to play with objects in scope and debug as if they were just irbin’ around. Like breakpoint, just not as fancy.
Here’s how to do it. We’ll call this simple script debug.rb.
require 'irb' module IRB def self.start_session(binding) IRB.setup(nil) workspace = WorkSpace.new(binding) if @CONF[:SCRIPT] 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("SIGINT") do irb.signal_handle end catch(:IRB_EXIT) do irb.eval_input end end end # we want to manipulate this in IRB two = 1 + 1 IRB.start_session(Kernel.binding)
So, what we’re doing is adding a method to the IRB module: start_session. This is basically a version of IRB’s normal start method with one nice addition: you can pass in a Binding object and have IRB use that binding.
Let’s run debug.rb:
$ ruby debug.rb >> two => 2 >> three NameError: undefined local variable or method `three' for Kernel:Module from (irb):1 from debug.rb:31
Since we setup two in debug.rb, it’s available to us in our irb prompt. Of course, we didn’t define three.
I’m sure there are a ton of uses for this. Joel VanderWerf, for instance, showed off a GUI application at the Silicon Valley Ruby Conference which had the ability to run an IRB session with the app’s current state for debugging.
Of course, breakpoint is the ultimate for doing things more complicated. But this trick works well for local projects.
Simply amazing.
Chime in.