"资源" - 红宝石宝石的目录

DeX*_*eX3 4 ruby gem ruby-c-extension

我目前正在尝试在Ruby中创建自己的gem.gem需要一些静态资源(比如ICO格式的图标).我在哪里将这些资源放在我的gem目录树中以及如何从代码中访问它们?

此外,我的扩展的一部分是本机C代码,我希望C部分也可以访问资源.

Mat*_*ira 7

您可以将资源放在任何您想要的位置,lib目录除外.因为它将成为Ruby的加载路径的一部分,所以应该存在的唯一文件是您希望人们使用的文件require.

例如,我通常将翻译后的文本存储在i18n/目录中.对于图标,我只是把它们放进去resources/icons/.

至于如何访问这些资源......我遇到了这个问题,我写了一个小宝石只是为了避免重复.

基本上,我一直这样做:

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/
Run Code Online (Sandbox Code Playgroud)

我将它包装成一个漂亮的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
Run Code Online (Sandbox Code Playgroud)

至于在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);
}
Run Code Online (Sandbox Code Playgroud)

现在您可以从Ruby访问它:

ico = Your::Ico.new path
Run Code Online (Sandbox Code Playgroud)