require_all

A wonderfully simple way to load your code.

Tired of futzing around with require statements everywhere, littering your code with require File.dirname(__FILE__) crap? What if you could just point something at a big directory full of code and have everything just automagically load regardless of the dependency structure?

Wouldn’t that be nice? Well, now you can!

require 'require_all'

You can use require_all in a multitude of different ways.

The easiest way to use require_all is to just point it at a directory containing a bunch of .rb files:

require_all 'lib'

This will find all the .rb files under the lib directory (including all subdirectories as well) and load them.

The proper order to in which to load them is determined automatically. If the dependencies between the matched files are unresolvable, it will throw the first unresolvable NameError.

You can also give it a glob, which will enumerate all the matching files:

require_all 'lib/**/*.rb'

It will also accept an array of files:

require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file? f }

Or if you want, just list the files directly as arguments:

require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'

Still have the require File.dirname(FILE) blues? The require_all gem also provides a require_rel statement which requires files to relative to the current file. So you can replace statements like:

require File.dirname(__FILE__) + '/foobar'

with just a simple require_rel:

require_rel 'foobar'

Even better, require_rel still has the full power of require_all, so you can use require_rel to load entire directories of code too. If “foobar” is a directory this will load all the .rb files found under that directory with automagic dependency handling.

It’s just that easy! Code loading shouldn’t be hard.

Methodology

I didn’t invent the approach this gem uses. It was shamelessly stolen from Merb (which apparently stole it from elsewhere). Here’s how it works:

  1. Enumerate the files to be loaded
  2. Try to load all of the files. If we encounter a NameError loading a particular file, store that file in a “try to load it later” list.
  3. If all the files loaded, great, we’re done! If not, go through the “try to load it later” list again rescuing NameErrors the same way.
  4. If we walk the whole “try to load it later” list and it doesn’t shrink at all, we’ve encountered an unresolvable dependency. In this case, require_all will rethrow the first NameError it encountered.

Questions? Comments? Concerns?

You can reach the author on github or freenode: “tarcieri”

Or by email: [email protected]

Got issues with require_all to report? Post ’em here:

Github Tracker

License

MIT (see the LICENSE file for details)