views:

1020

answers:

1

Some Ruby librararies I'm using use require statements like this:

require File.dirname(__FILE__) + '/specification_helper.rb'

lib_dir = File.expand_path(File.join(File.dirname(__FILE__), "lib"))

require File.join(File.dirname(__FILE__), 'lib/tools', 'version')

require File.expand_path(File.join(File.dirname(__FILE__), 'datautils', 'conn'))

Doesn't this format make your code needlessly dependent on the structure of the file system?

Why did the author do it this way?

Would it be possible to (safely) alter this code to remove this dependency on the filesystem?

+2  A: 

I actually use this scheme in production code.

Requiring files relative to the current source location has several advantages :

  • the source tree can be moved around as a whole and remains usable since we require sources relatively to each other.
  • since we use full paths, we avoid accidental collisions (loading a source with the same name in another library, or reloading the same source twice)
  • the code can be used without having to modify ruby's search path


Should you prefer to use a modified ruby search path, you can do it in multiple ways :

  1. adding -I options on the ruby command line
  2. modifying the $LOAD_PATH variable within the sources
  3. playing with the environment variable RUBYLIB

Solution 1 implies controlling how ruby is invoked. You'll need a script to start the program, such as:

@echo off
REM my_script.cmd
set srcdir=%~dp0\..\path\to\source
ruby -I %srcdir% %srcdir%\my_script.rb

Or:

#!/bin/sh
srcdir=$(cd $(dirname $0)/../path/to/source && pwd)
exec ruby -I $srcdir $srcdir/my_script.rb

Solution 2 is workable but does not avoid collisions. You'll typically do something like :

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))

Solution 3 is unadvisable, the less dependencies you'll have toward environment variables, the better you will be.

bltxd