Skip to content

Improve `debugger` so that an IRB session is started when ruby-debug is not loaded.

gitlab-qa-bot requested to merge minimal_debugger into master

Created by: myronmarston

This is just crazy, random idea I had today. I'm looking for feedback more than anything at this point.

I frequently receive the use -d or --debug warning, for a few reasons:

  • At work, I'm building lots of new small, internal gems, and I don't pull in a debugger gem as a dependency until I really need it...so I'll be working on something, and will put debugger in a spec, and won't realize it can't work yet.
  • Occasionally, I need to debug a spec failure on our CI server, where we usually bundle install --without debugger--so ruby-debug isn't installed.
  • For a while after I started using 1.9.3, there wasn't a viable debugger gem to use. There still isn't a 1.9.3 compatible release of ruby-debug. cldwalker/debugger has dealt with this problem and I use that now, but it was frustrating to not have a debugger for a while. It may happen again (e.g. with the release of ruby 1.9.4 or 2.0).

90% of the time, I don't need the power of a full debugger--I just want to poke around in an IRB session at a particular point in the code. It turns out, we can easily provide that functionality directly in rspec for cases when a debugger is not loaded. So...this is a first pass implementation that makes our debugger print a message and start an IRB session with self set to the receiver of debugger. Here's what the output looks like:

*****************************************************************
A `debugger` statement has been encountered but ruby-debug is not
loaded. For a full debugger, install `ruby-debug` and use the -d
or --debug option.

The `debugger` statement was encounted at:
/Users/myron/code/rspec-dev/repos/rspec-core/spec/rspec/core/example_spec.rb:21:in `block (3 levels) in <top (required)>'

      16    end
      17  end
      18
      19  describe "#exception", :focus do
      20    it "supplies the first exception raised, if any" do
 =>   21      debugger
      22      example = example_group.example { raise "first" }
      23      example_group.after { raise "second" }
      24      example_group.run
      25      example.exception.message.should eq("first")
      26    end

We've setup an IRB sessionso you can poke around here
a bit. Type `exit` to continue.
*****************************************************************

A couple thoughts/concerns I have:

  • A debugger doesn't really belong in rspec-core. Adding this opens up the door to people requesting additions to it (e.g. next, step, up/down the callstack, etc), but I think it's important we don't go down that route. What's here is appealing to me because it's just IRB, which is already in the stdlib.
  • This has the potential to break non-interactive spec runs (e.g. on a CI server or whatever). Before, debugger would just print a warning and continue happily on its way...now it stops and waits for user input. Is there a way to tell if rspec is running in an interactive terminal?
  • There are some extra edge cases this needs to handle (e.g. listing needs to handle source files that have less than 11 lines of code; sandboxing ARGV since IRB picks up on those). (I'm mostly mentioning these so I don't forget, if we do decide to merge this).

Thoughts?

Merge request reports