2011-12-20 50 views
7

我只是在研究我的第一個寶石(對於ruby來說也很新穎),到目前爲止的整個代碼都在這裏;在寶石中使用yaml文件

https://github.com/mikeyhogarth/tablecloth

有一件事我一直試圖做的是創造出寶石可以作爲查找訪問(位於lib /桌布/ YAML/qty.yaml)YAML文件。這一切都很好,單元測試全部通過,但是當我構建和安裝gem並嘗試在irb下運行(從我的home文件夾)時,我正在獲得;

Errno::ENOENT: No such file or directory - lib/tablecloth/yaml/qty.yaml 

代碼現在正在尋找〜/ lib/tablecloth中的文件...而不是在gem安裝到的目錄中。所以我的問題是;

1)我應該如何更改recipe.rb的第27行,以便它在安裝了gem的文件夾中查找?

2)我是否實際上錯誤地處理了這件事(是否適合在這種方式下使用gem中的靜態yaml文件)?

回答

14

那麼首先你應該參考該文件在以下方式:

file_path = File.join(File.dirname(__FILE__),"yaml/qty.yaml") 
units_hash = YAML.load_file(filepath) 

File.dirname(__FILE__)讓你在當前文件(recipe.rb)所在的目錄。 File.join以正確的方式連接文件路徑。所以你應該使用它來將yaml文件相對引用到recipe.rb文件夾。

如果在這種情況下使用YAML文件是一個好主意,這是一個廣泛討論的問題。我自己認爲,這是一個適當的方式,特別是在用紅寶石開發的時候。

yaml-files的一個有效替代方案是rb-File(Ruby Code),其中聲明瞭包含數據的常量。稍後您可以直接使用它們。通過這種方式,只有ruby解釋器必須工作,並且可以爲其他事情節省計算時間。 (不需要解析器)

但是,在正常情況下,您還應該注意,讀取YAML文件可能會失敗。所以,你應該能夠處理:

file_path = File.join(File.dirname(__FILE__),"yaml/qty.yaml") 
begin 
    units_hash = YAML.load_file(filepath) 
rescue Psych::SyntaxError 
    $stderr.puts "Invalid yaml-file found, at #{file_path}" 
    exit 1 
rescue Errno::EACCES 
    $stderr.puts "Couldn't access file due to permissions at #{file_path}" 
    exit 1 
rescue Errno::ENOENT 
    $stderr.puts "Couldn't access non-existent file #{file_path}" 
    exit 1 
end 

或者,如果你不關心細節:

file_path = File.join(File.dirname(__FILE__),"yaml/qty.yaml") 
units_hash =  
    begin 
    YAML.load_file(filepath) 
    rescue Psych::SyntaxError, Errno::EACCES, Errno::ENOENT 
    {} 
    end 
+1

謝謝。說實話,我這樣做的唯一原因是因爲我剛剛讀完的這本書表明這是最佳實踐(代碼中沒有神奇數字,非程序員可編輯等),但我確實遵循了你的觀點,並會可能會在某些時候改變這一點。 – 2011-12-20 09:38:57