Question

Imagine you have an executable foo.rb, with libraries bar.rb layed out in the following manner:

<root>/bin/foo.rb
<root>/lib/bar.rb

In the header of foo.rb you place the following require to bring in functionality in bar.rb:

require File.dirname(__FILE__)+"../lib/bar.rb"

This works fine so long as all calls to foo.rb are direct. If you put as say $HOME/project, and symlink foo.rb into $HOME/usr/bin, then __FILE__ resolves to $HOME/usr/bin/foo.rb, and is thus unable to locate bar.rb in relation to the dirname for foo.rb.

I realize that packaging systems such as rubygems fix this by creating a namespace to search for the library, and that it is also possible to adjust the load_path using $: to include $HOME/project/lib, but it seems as if a more simple solution should exist. Has anyone had experience with this problem and found a useful solution or recipe?

Was it helpful?

Solution

I know this is ages old, but I just found this:

require 'pathname'
APP_ROOT = File.join(File.dirname(Pathname.new(__FILE__).realpath),'..')

OTHER TIPS

You can use this function to follow any symlinks and return the full path of the real file:

def follow_link(file)
  file = File.expand_path(file)

  while File.symlink?(file)
    file = File.expand_path(File.readlink(file), File.dirname(file))
  end

  file
end

puts follow_link(__FILE__)

Probably worth mentioning that + works nicely with Pathname objects and also there is Kernel.Pathname method, so @Burke's original code could be made even shorter:

require 'pathname'
APP_ROOT = Pathname.new(__FILE__).realpath + "../../lib"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top