2012-06-15 203 views
3

我目前正在嘗試在Ruby中創建自己的寶石。該寶石需要一些靜態資源(例如ICO格式的圖標)。我在哪裏可以將這些資源放在我的gem目錄樹中,以及如何從代碼訪問它們?「資源」 - 紅寶石寶石的目錄

此外,我的擴展的部分是本機C代碼,我希望C部分也可以訪問資源。

+0

好吧,我找到了一種方法,通過使用__FILE__在Ruby代碼中做到這一點,但這對我來說似乎很骯髒...... – DeX3

+0

是的,這就是我會做的。沒有其他好方法:/(至少,我能想到;我可能是錯的) – Jwosty

+0

你想要一種方式來乾淨地訪問'lib'目錄之外的gem文件,或者你在尋找面向對象的方式來處理您的資源? –

回答

4

除了在lib目錄中,您可以隨時隨地放置資源。由於它將成爲Ruby加載路徑的一部分,因此只有那些您希望人們訪問require的文件。

例如,我通常將譯文存儲在i18n/目錄中。對於圖標,我只是把它們放在resources/icons/

至於如何訪問這些資源......我碰到這個問題,足夠的I wrote a little gem只是爲了避免重複。

基本上,我在做這一切的時候:

def Your::Gem.root 
    # Current file is /home/you/code/your/lib/your/gem.rb 
    File.expand_path '../..', File.dirname(__FILE__) 
end 

Your::Gem.root 
# => /home/you/code/your/ 

我裹着這成一個漂亮的DSL,增加了一些額外的便利的東西,並結束了與此:

class Your::Gem < Jewel::Gem 
    root '../..' 
end 

root = Your::Gem.root 
# => /home/you/code/your/ 

# No more joins! 
path = root.resources.icons 'your.ico' 
# => /home/you/code/your/resources/icons/your.ico 

至於在C中訪問您的資源,path只是一個Pathname。你可以將它作爲一個字符串傳遞給C函數,打開文件並做你需要做的事情。你甚至可以將對象返回到Ruby世界:

VALUE your_ico_new(VALUE klass, VALUE path) { 
    char * ico_file = NULL; 
    struct your_ico * ico = NULL; 

    ico_file = StringValueCStr(path); 
    ico = your_ico_load_from_file(ico_file); /* Implement this */ 
    return Data_Wrap_Struct(your_ico_class, your_ico_mark, your_ico_free, ico); 
} 

現在你可以在Ruby訪問:

ico = Your::Ico.new path