Finding relative libraries when using symlinks to ruby executables
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
resolves to __FILE__
$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?
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"