суббота, 15 декабря 2007 г.

YAML-конфиги

Поработав некоторое время с конфигурационным файлами в формате YAML, вы заметите, что встроенного простого метода для синхронизации изменений нет. Чтобы каждый раз не расписывать однородные конструкции для записи изменений, я написал маленькое расширение:

module YAML
def self.set_connection(path)
data = load_file(path).symbolize_keys
class << data
attr_accessor :path
def sync
File.open(@path, 'w+') { |file| file.puts(self.stringify_keys.to_yaml) }
end
end
data.path = path
data
end
end



Заметьте, что я также автоматом применяю symbolize_keys, когда вытаскиваю данные из yaml, и stringify_keys, когда отправляю обратно изменения. Все это сделано по простой причине, что у меня на верхнем уровне конфига всегда находится хэш (со строками в качестве ключей, так как они смотрятся более органично в yaml чем символы, на моей взгляд), а в коде уже удобнее работать с символами для доступа к отдельным разделам конфига. Можно было, конечно, проверять является ли хэшем выгружаемая информация и, в случае, положительного ответа, применять эти функции, но кто захочет - сам сделает, а для моих целей этого достаточно.

Пример из скрипта, который я использую для управления рейлс приложениями:

$config = YAML.set_connection('config.yaml'.in_current_dir)
#...
mode 'config' do
keyword('repository', 'r') do
default $config[:repository]
#...
end

keyword('rails_apps') do
default $config[:rails_apps]
#...
end

def run
#...
%w(repository rails_apps).each { |setting| $config[setting.to_sym] = params[setting].value }
$config.sync
end
end