Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"resources"-directory for ruby gem

I'm currently experimenting with creating my own gem in Ruby. The gem requires some static resources (say an icon in ICO format). Where do I put such resources within my gem directory tree and how to I access them from code?

Also, parts of my extension are native C code and I would like the C-parts to have access to the resources too.

like image 296
DeX3 Avatar asked Jun 15 '12 13:06

DeX3


1 Answers

You can put resources anywhere you want, except in the lib directory. Since it will be will be part of Ruby's load path, the only files that should be there are the ones that you want people to require.

For example, I usually store translated text in the i18n/ directory. For icons, I'd just put them in resources/icons/.

As for how to access these resources... I ran into this problem enough that I wrote a little gem just to avoid repetition.

Basically, I was doing this all the time:

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/

I wrapped this up into a nice DSL, added some additional convenience stuff and ended up with this:

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

As for accessing your resources in C, path is just a Pathname. You can pass it to a C function as a string, open the file and just do what you need to do. You can even return an object to the Ruby world:

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);
}

Now you can access it from Ruby:

ico = Your::Ico.new path
like image 118
Matheus Moreira Avatar answered Oct 12 '22 22:10

Matheus Moreira