現在、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