2008-11-27 28 views
5

想象一下,你有一個可執行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和$符號鏈接foo.rb放入$HOME/usr/bin,則__FILE__解析爲$HOME/usr/bin/foo.rb,因此無法找到與foo.rb的dirname相關的bar.rb

我意識到,包裝系統等的RubyGems通過創建一個命名空間搜索庫解決這個問題,而且還可以使用$:包括$HOME/project/lib調整LOAD_PATH,但它好像一個更簡單的解決方案應存在。有沒有人有過這個問題的經驗,並找到一個有用的解決方案或配方?

回答

11

我知道這是舊的時代,但我發現這一點:

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

這絕對更好,至少它只是兩條線。仍然不幸的是,沒有單一的解決方案。 – dgtized 2009-12-18 00:23:20

2

您可以使用此功能,遵循任何符號鏈接,並返回真實文件的完整路徑:

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

我想這是有效的。對於那些應該是文件中第一個要求的東西,這不是一個真正的快樂解決方案。我對包含該文件片段的解決方案感到不滿意,以便找到我們從哪裏調用它。 – dgtized 2008-11-30 09:28:43

1

可能值得一提的是+Pathname很好地配合使用,也有Kernel.Pathname的方法,所以@Burke的原碼可以做得更短:

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