I released a little gem this week that helps to deal with what can be an annoying issue in larger ruby projects: requires. Unfortunately, relative requires will always be relative to the file that launched the application, not to the file making the require itself. What a pain. This means that if you’re launching your application from rake, from a test suite or from the command line, you need to rely on some trick. These include unshifting your lib directory onto the load path or using the File.dirname(__FILE__) trick. Both are cumbersome and a bit annoying, but I think each has a far more detrimental side-effect: readability.

If I’ve unshifted lib onto the $PATH variable, I make all requires within my application (or gem, etc.) as though they are being made from the base of the lib directory. Ok, this gives us a convention, but it also gives us a lot of confusion. And, more importantly, we can not take any file, at any time, and run it! I want every ruby file I write to be self containing and explicitly define it’s dependencies. I want every ruby file I write to be able to be loaded into irb without consequences. Need is a gem that helps with these problems.

To use need, simply “need” a file using a relative path from the file that has the dependency. And that’s it. This will work no matter where you application is launched from. And your file can always be loaded directly into irb. And the dependencies are clear (as are their locations from the file itself) without knowing any extra application-level magic. To use need, just do:

require 'rubygems'; require 'need'
need{"relative/path/to/file"}

Need is implemented as an extension to Object and it uses the binding of the block (yes, those curly braces are needed in the call, no pun intended) to remember the scope of the file where need was called, and hence eval __FILE__ with that file’s location and not the location of the Object extension file itself.

What are you waiting for, install it now:

sudo gem install need

Drop me a line if you have any questions, and happy needing!