From: Joel VanderWerf Date: 2008-04-15T08:16:41+09:00 Subject: Re: How to reliably setup require path Christian Johansen wrote: > I'm writing my first Ruby command line application (beyond a simple > script) and I'm little unsure about how to structure the application and > the best use of require. I've come as far as to have the following file > structure: > > myapp/ > bin/ > myapp > docs/ (RDOC files) > lib/ > myapp.rb > myapp/ > files and folders here > test/ (Test::Unit tests) > > And the application is working, but there are a few things of which I am > unsure: > > The bin/myapp file is a symlink to the lib/myapp.rb file which has a > shebang line. This doesn't really work, because inside lib/myapp.rb I > have: > > require 'myapp/file' > require 'myapp/module/file' > > which doesn't make sense when running the application from anywhere else > than myapp/lib > > I also tried > > $MYAPP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), > 'myapp')) > $LOAD_PATH << File.expand_path($MYAPP_ROOT) > > Which still doesn't work because this also relies on cwd... > > How do I work around this? What's the best practice way of making these > things make sense? Do you use the $RUBYLIB variable to set the full path > to the application? I was hoping to create the application as standalone > as possible, so installation will be easy. I'd do a couple of things differently (and I've used this pattern in a number of applications with the same dir structure as yours): 1. make bin/myapp a very short ruby script instead of a symlink (if you want this to work on windows, symlinks won't work anyway). 2. use unshift instead of <<, so you get precedence 3. use an ENV var instead of a global so child scripts can use it 4. use File.dirname to go up two levels instead of one, so that you can use it to find non-lib files as well (images for example, or other data files). Note that the expand_path call has to happen before calling dirname twice. Here's the code: ENV['MYAPP_BASE'] = File.dirname(File.dirname(File.expand_path(__FILE__))) libdir = File.join(ENV['MYAPP_BASE'], "lib") $LOAD_PATH.unshift libdir ENV['RUBYLIB'] = libdir + ":" + ENV['RUBYLIB'] HTH. -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407