Wednesday, October 24, 2007

Debugging a JRuby on Rails app with jruby-debug and NetBeans

We've been working on the java port of ruby-debug for awhile and it's getting perilously close to usable. And with the latest builds of NetBeans, you can actually use the NB ruby debugger with it. If you're very brave, you can try it for your yourself. Be warned, it's still a work in progress, but here's how to get started:

  1. Check out jruby from trunk and build it. You'll need java and ant, but if you're interested in jruby chances are good you have those already. It's super easy to build, check it out from http://svn.codehaus.org/jruby/trunk and do ant dist and you're good to go.
  2. Check out jruby-debug from http://debug-commons.rubyforge.org/svn/jruby-debug/trunk. In this directory, do rake install_gem. This will compile and build a jruby version ruby-debug-base, which ruby-debug (command line rdebug debugger) and ruby-debug-ide (which NetBeans and Eclipse use) both depend on.
  3. Check out ruby-debug-ide from http://debug-commons.rubyforge.org/svn/trunk/ruby-debug-ide. Then do a rake gem to build the gem and gem install pkg/ruby-debug-ide-0.1.8.gem to install it.
  4. Grab a copy of NetBeans daily builds ruby ide from here: http://deadlock.netbeans.org/hudson/job/ruby/
  5. Fire up NetBeans like with some extra command line switches: ./netbeans -J-Dorg.netbeans.modules.ruby.debugger.force.rdebug=true -J-Dorg.netbeans.modules.ruby.debugger.fast.not.required=true
    The first tells NetBeans to always use the fast debugger even tho the classic debugger is what appears selected in the UI. The second tells NB to ignore the fact that the classic debugger is selected and allow us to debug a rails app anways. These flags were just added to allow us to play with jruby-debug in NetBeans for now, they won't be necessary once jruby-debug matures a little and full support for it comes into NB.
  6. In NetBeans Tools | Options be sure and have your ruby interpreter pointing at the jruby you built from trunk in Step 1.
You should now be able to debug Ruby and ROR apps using the fast ruby debugger inside of jruby. Like I said, this is all very experimental. All these steps will go away in the next few weeks or months and jruby-debug, jruby, NetBeans, ruby-debug-ide do releases.

Things which seem to work ok:
  • setting breakpoints
  • looking at variables (global and local)
  • watches
A little flaky (tho it may already be fixed by the time you read this):
  • Stepping over some code in Rails
  • Stepping out of a method
Finally, big time kudos to Martin for kicking this whole thing off and Peter for knocking out bugs and implementing more features every hour just about. It's definitely looking close now.

Sunday, October 21, 2007

Avoiding Helpful Tools Considered Stupid

Rarely does a blog post get me all fired up like Giles Bowketts here. As part of the team working on improving debugging support for JRuby, it probably struck a particularly personal chord. Nothing like having your hard work publicly ridiculed to get you exicted. I might have ignored it, and maybe I probably should, but the post contains some truly exceptional BS that needs to be addressed.

First off, it claims to inspired by a good friend of mine. So Giles, to quote from that famous vice presedential debate: I know Jim Weirich, and you sir, are no Jim Weirich! Ok, so maybe Giles didn't actually claim to be Jim Weirich, but the fact that he even attributed Jim in any way while spouting such blatent poppycock just shouldn't be.

As part of my job I have the incredible good fortune to pair with Jim on a Rails project. At the risk of pointing out what should be obvious, we do write test cases. And, it's true, when we first started working together, we did not use a debugger. Most of the time, we didn't need one. But every so often, we would have a situation where we couldn't understand what some code was doing. More embarrassing still, sometimes it was even code that we wrote.

So, when confronted with such a situation, when we couldn't think of any more test cases to write, we would add statements like this to our code "puts DBG: #{some_value_we_want_to_see}". Wow, perty high tech, eh? And it worked. We could always solve our problem this way. Jim even had a little rake task that would comb thru the code to find DBG: in our code so we could easily remove these when we were done.

Then one day I got tired of us typing DBG: in our code and I said something like "Let's try using rdebug". And guess what: rdebug was often handier than adding puts statements to our code. We could inspect all kinds of stuff. Sometimes it helped us learn more about how Rails works, especially when it did things that were, umm, a little unexpected. It was a good thing. So much so, in fact, Jim spent some time working on getting it working better with emacs so it was even easier to use.

And, hard to believe tho it may be, it did not cause us to write less test cases. Every time we learned something while debugging, we could go back and write a test case which documented our learning. In the end it helped us to write more and better test cases because we were actively trying to do so.

So it should be obvious, but since it didn't seem to be I'll state it: debuggers are tools. Like any tool, if it helps you do your work better, you might want to use it. If it doesn't you probably shouldn't. Using a tool does not lead to bad habits, bad habits lead to using a tool incorrectly. And it's worth pointing out, the technique of classifying a technology or tool as bad because it can be used incorrectly is exactly the argument that I hear made against metaprogramming and run time type checking. Kind of ironic.