Bauble, Bauble...

Posted by Uncle Bob on 07/20/2008

In Ruby, I hate require statements that look like this:

require File.dirname(__FILE__)+"myComponent/component.rb"

So I decided to do something about it.

This all started when my Son, Micah, told me about his Limelight project. Limelight is a jruby/swing GUI framework. If you want to build a fancy GUI in Ruby, consider this tool.

I have neither the time nor inclination to write a framework like this; but my curiosity was piqued. So in order to see what it was like to do Swing in JRuby I spent a few hours cobbling together an implementation of Langton’s Ant. This turned out to be quite simple.

The result, however, was a mess. There was swing code mixed up with “ant” code, in the classic GUI/Business-rule goulash that we “clean-coders” hate so much. Despite the fact that this was throw-away code, I could not leave it in that state – the moral outrage was just too great. So I spent some more time separating the program into two modules.

The first module knew all about Langton’s ant, but nothing about Swing. The second module was a tiny framework for implementing cellular automata in Swing. (Here are all the files).

I was quite happy with the separation, but did not like the horrible require statements that I had to use. The cellular_automaton component had two classes, in two separate files. In order to get the require right, I had to either use absolute directory paths, or the horrible File.dirname(__FILE__)... structure.

What I wanted was for cellular_automaton to behave like a gem. But I didn’t want to make it into a gem. Gem’s are kind of “heavy” for a dumb little thing like “cellular_automaton”.

So I created a module named “Bauble” which gave me some gem-like behaviors. Here it is:

module Bauble

 def self.use(bauble)

   bauble_name = File.basename(bauble)

   ensure_in_path "#{bauble}/lib"

   require bauble_name

 end

 def self.ensure_in_path(path)

   $LOAD_PATH << path unless $LOAD_PATH.include? path

 end

end

This is no great shakes, but it solved my problem. Now, in my langton’s ant program all I need to do is this:

require 'bauble'

Bauble.use('../cellular_automaton')

All the ugly requires are gone.

I’m thinking about turning Bauble into a rubyforge project, and making a publicly available gem out of it in order to give folks a standard way to avoid those horrible __FILE__ requires. I think there are several other utilities that could be placed in Bauble such as require_relative etc.

Anyway, what do you think?

Comments

Leave a response