2012-06-15 51 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