Mucking around with the library search path in ruby isn't exactly the hardest thing in the world. It's just a matter of fiddling around with a horrible looking perlish global variable and using __FILE__ to munge the right path together. Again, nothing too difficult but it's annoying and ugly—totally out of place next to all that beautiful ruby code.
For the most part, this isn't much of a problem for libraries. In fact, you don't normally want to hard code paths anyway. Typically a flag is passed to the ruby interpreter:
$ ruby -Isome/path foo.rb
However, in some cases you still need to change the path in the code. Likely the most common place this shows up is within test/spec files. Does this look familiar?
# some_cool_spec.rb
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
require 'lib_under_test'
context '...' do
# snip
end
It’s so ugly, right? To me it's quite the eyesore so I wrote the following really simple library (rubylib.rb) to fix it up a bit:
module LibCommands
def lib(*path_segs)
$:.unshift File.join(*path_segs)
end
def lib_rel(*path_segs)
file = caller.first.split(':').first
lib File.dirname(file), *path_segs
end
end
Object.send :include, LibCommands
Now when you want to add something to the load path, you can just use the lib method:
lib 'path', 'to', 'library'
It's even better when dealing with relative paths. lib_rel specifies the directory to add relative to the file it's called from—rather than the current working directory, which is probably different. That makes the above rspec:
# some_cool_spec.rb
lib_rel '..', 'lib'
require ‘lib_under_test’
context '...' do # snip end
Nice, eh? Sure, but you still need to require rubylib.rb first. You can fix that up with a few little tricks used by rubygems. First, create aubylib.rb that just requires rubylib.rb. That way it looks nicer when you add it in as a flag to ruby.
$ ruby -rubylib foo.rb
The next level of laziness is to add it you your RUBYOPT. With the environment variable set the two commands are available without any explicit requires:
$ export RUBYOPT="${RUBYOPT} -rubylib"
$ ruby foo.rb
