2012-06-15 1 views
3

В настоящее время я экспериментирую с созданием собственного драгоценного камня в Ruby. Драгоценный камень требует некоторых статических ресурсов (например, значок в формате ICO). Где я могу разместить такие ресурсы в моем дереве каталогов gem и как получить доступ к ним из кода?"resources" -directory для ruby ​​gem

Кроме того, части моего расширения являются родным кодом C, и я хотел бы, чтобы C-части имели доступ к ресурсам тоже.

+0

Хорошо, я нашел способ сделать это с помощью __FILE__ из кода рубина, но это кажется довольно грязным для меня ... – DeX3

+0

Да, это то, что я бы сделал. На самом деле нет другого хорошего способа:/(по крайней мере, я могу думать, я могу ошибаться) – Jwosty

+0

Хотите ли вы получить чистый доступ к файлам gem, которые находятся за пределами каталога 'lib', или вы ищете объектно-ориентированный способ работы с вашими ресурсами? –

ответ

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