Ответ 1
Вы можете перебирать узлы на более низком уровне, сохраняя комментарии при испускании. Кроме того, вы можете увидеть, дает ли механизм syck результат, который вы ищете.
Согласно http://yaml.org/spec/current.html#id2509980 комментарии в файлах YAML представляют собой презентационную деталь и не должны быть в графе сериализации/представления (http://yaml.org/spec/current.html#representation/). Похоже, что Psych разбирается в соответствии со спецификацией и теряет комментарии, что означает, что невозможно проанализировать файл YAML и сериализовать его снова точно так же, когда файл содержит комментарии. Что, на мой взгляд, очень странно, потому что комментарии имеют значение в таком файле (например, configs).
Кто-нибудь знает, возможно ли разобрать комментарии в существующей библиотеке или это единственный способ сделать это самостоятельно?
Вы можете перебирать узлы на более низком уровне, сохраняя комментарии при испускании. Кроме того, вы можете увидеть, дает ли механизм syck результат, который вы ищете.
Мы также можем сделать что-то подобное, что изменит значение ключа, а также сохранит комментарии.
require 'yaml'
thing = YAML.load_file('/opt/database.yml')
hostname = thing["common"]["host_name"]
appname = thing["common"]["app_name"]
motdobj = IO.readlines('/opt/database.yml')
motdobj = motdobj.map {|s| s.gsub(hostname, "mrigesh")}
motdobj = motdobj.map {|s| s.gsub(appname, "abc")}
File.open('/opt/database.yml', "w" ) do | file1 |
file1.puts motdobj
file1.close
end
Мне понравилась сумасшедшая идея @josh-voigts. Здесь сумасшедшая реализация. Комментарии могут чередоваться практически везде, и это работает!
require 'tempfile'
def yaml_conf_edit(fn, &block)
conf = File.open(fn) {|f| YAML.load(f.read)}
before = Tempfile.new('before')
before.write(conf.to_yaml)
before.close
yield conf
after = Tempfile.new('after')
after.write(conf.to_yaml)
after.close
'merge #{fn} #{before.path} #{after.path}'
before.unlink; after.unlink
conf
end
Что вы можете использовать в чем-то вроде:
yaml_conf_edit('conf/database.yml') do |conf|
conf['development']['database'] = db_timestamped
end