I’ve had an on-again off-again relationship with Objective-C and Cocoa. I wrote a artsy visualization in it that ended up in some museums, a rather crappy utility to transfer email between IMAP servers, and some other stuff.
But I always became really frustrated with how hard it was to test drive any of this code. Granted, test-driving graphics and UI code can be hard, but I really love the clarity BDD process gives you when you’re hacking something together. And so I eventually lost interest.
Enter MacRuby. It’s now possible to use Ruby to test drive your Objective-C code, and I’m loving it (mostly). Seriously, go read this tutorial and try it out.
I used this method to develop an XML-Pull Parser in Objective-C called Opal – something I’ve long missed in both Objective-C and Ruby. Download it, and build the ‘Test’ target to see how the specs run. The Build window doesn’t open automatically, so you’ll need to hit Command-Shift-B to open it.
You’ll see some failures there if you haven’t installed the Bacon gem for MacRuby of course:
$ sudo macgem install bacon
I’m using the tiny Bacon library to spec my code because RSpec has trouble running under Ruby 1.9, which is the version MacRuby supports. RSpec 2.0 should fix this. You can also try out other ruby testing libraries of course, though Bacon is pretty good for what I need to do.
Caveats
While I’m really happy that I’m finally able to use a truer BDD workflow in an Objective-C environment, I’m less happy with the interfaces I have to use. The specs are run during the XCode build process, so I have to pour through Bacon’s output within a giant text window:
It’s not preventing me from getting stuff done, but I spend way more time pouring through this output than I should. There’s also no way to click through to the spec failures, nor a way to run a single spec. I suspect the only way I’d get this is if I roll my own command line interfaces, probably integrated with TextMate.
Once last caveat. While MacRuby’s been a very solid way to interface with the Objective-C runtime, it’s actually not a very solid Ruby interpreter. That makes sense – they’ve been focusing on the integration of the two languages more than shipping a Ruby interpreter. MacRuby 0.6 passes 85% of the RubySpecs, but I’d still think twice before I started a MacRuby project with lots of Ruby code. Or I’d use Cocoa or Foundation libraries where I could – like NSURLConnection over Net::HTTP for example.