2008-11-27 14 views
5

Wyobraź masz wykonywalnego foo.rb, z bibliotekami bar.rb layed się w następujący sposób:Znalezienie biblioteki względne przy użyciu dowiązania do ruby ​​wykonywalne

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

W nagłówku foo.rb umieścić poniżej wymagane do wprowadzenia funkcji w pliku bar.rb:

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

Działa to dobrze, o ile wszystkie wywołania foo.rb są bezpośrednie. Jeśli wstawisz jako przykład $ HOME/project i dowiązanie symboliczne foo.rb do $HOME/usr/bin, wówczas __FILE__ rozwiąże się na $HOME/usr/bin/foo.rb, a zatem nie będzie w stanie zlokalizować bar.rb w odniesieniu do dirname dla foo.rb.

Zdaję sobie sprawę, że systemy opakowaniowe takie jak RubyGems rozwiązać ten problem poprzez stworzenie przestrzeni nazw, aby szukać w bibliotece, i że jest to również możliwe, aby dostosować load_path użyciu $: zawierać $HOME/project/lib, ale wydaje się, że bardziej proste rozwiązanie powinno istnieć. Czy ktoś miał doświadczenie z tym problemem i znalazł przydatne rozwiązanie lub przepis?

Odpowiedz

11

wiem, że to wieki stary, ale ja po prostu znaleźć to:

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

To zdecydowanie lepiej, przynajmniej to tylko dwie linie. Nadal niefortunne, że nie ma jednego rozwiązania liniowego. – dgtized

2

Można użyć tej funkcji, aby śledzić dowiązania i przywrócić pełną ścieżkę prawdziwego pliku:

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__) 
+0

Przypuszczam, że działa. Naprawdę niezbyt szczęśliwe rozwiązanie dla czegoś, co ma być pierwszym wymaganiem w pliku. Nie jestem zadowolony z rozwiązania, które zawiera ten fragment w każdym pliku, aby znaleźć miejsce, z którego został wywołany. – dgtized

1

Warto wspomnieć, że + dobrze współpracuje z obiektami Pathname, a także istnieje metoda Kernel.Pathname, więc oryginalny kod Burka może być jeszcze krótszy:

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