Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"require File.dirname(__FILE__)" -- how to safely undo filesystem dependency?

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?

like image 938
terrestrial Avatar asked Jun 25 '09 12:06

terrestrial


1 Answers

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.

like image 86
bltxd Avatar answered Nov 02 '22 10:11

bltxd