我目前正在尝试在 Ruby 中创建自己的 gem。gem 需要一些静态资源(比如 ICO 格式的图标)。我应该将这些资源放在我的 gem 目录树中的什么位置,以及如何从代码中访问它们?
此外,我的扩展部分是本机 C 代码,我希望 C 部分也可以访问资源。
我目前正在尝试在 Ruby 中创建自己的 gem。gem 需要一些静态资源(比如 ICO 格式的图标)。我应该将这些资源放在我的 gem 目录树中的什么位置,以及如何从代码中访问它们?
此外,我的扩展部分是本机 C 代码,我希望 C 部分也可以访问资源。
您可以将资源放在任何您想要的位置,除了在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/
我把它包装成一个很好的 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