Поиск относительных библиотек при использовании символических ссылок на исполняемые файлы ruby - PullRequest
5 голосов
/ 27 ноября 2008

Представьте, что у вас есть исполняемый файл foo.rb с библиотеками bar.rb, расположенными следующим образом:

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

В заголовке foo.rb вы помещаете следующее требование для добавления функциональности в bar.rb:

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

Это прекрасно работает, если все вызовы foo.rb прямые. Если вы положите, скажем, $ HOME / project и symlink foo.rb в $HOME/usr/bin, то <code>__FILE__ разрешится в $HOME/usr/bin/foo.rb и, таким образом, не сможет найти bar.rb относительно имени dirname для foo.rb.

Я понимаю, что системы упаковки, такие как rubygems, исправляют это, создавая пространство имен для поиска в библиотеке, и что также можно настроить путь загрузки, используя $:, чтобы включить $HOME/project/lib, но кажется, что более простое решение должно существовать. Кто-нибудь имел опыт решения этой проблемы и нашел полезное решение или рецепт?

Ответы [ 3 ]

12 голосов
/ 21 апреля 2009

Я знаю, что это возраст, но я только что нашел это:

require 'pathname'
APP_ROOT = File.join(File.dirname(Pathname.new(__FILE__).realpath),'..')
2 голосов
/ 27 ноября 2008

Вы можете использовать эту функцию для перехода по любым символическим ссылкам и возврата полного пути к реальному файлу:

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__)
1 голос
/ 20 апреля 2010

Вероятно, стоит упомянуть, что + прекрасно работает с Pathname объектами, а также существует метод Kernel.Pathname, поэтому исходный код @ Burke можно сделать еще короче:

require 'pathname'
APP_ROOT = Pathname.new(__FILE__).realpath + "../../lib"
...