У меня есть этот старый код, использующий Sych
:
yaml_as "tag:yaml.org,2002:#{self}"
def to_yaml(opts = {})
YAML::quick_emit(self, opts) do |out|
out.map(taguri, to_yaml_style) do |map|
map.add('name', name)
map.add('address', full_address.upcase) if full_address?
end
end
end
который выводит что-то вроде этого:
--- !Contact
name: SMOKE OIL
address: |-
SMOKE OIL
1 RUE DE LA PAIX
75002 PARIS
FRANCE
Теперь я обновляю этот старый код, переходя на Psych
, поэтому я прочитал документ и сделал:
yaml_as "tag:yaml.org,2002:#{self}"
def encode_with(coder)
coder['name'] = name
coder['address'] = full_address.upcase if full_address?
end
И это делает:
--- !Contact
name: SMOKE OIL
address: ! "SMOKE OIL\n1 RUE DE LA PAIX\n75002 PARIS\nFRANCE"
Это хороший YAML, но он должен быть результатом сервера whois, и он менее удобочитаем для людей…
Итак, я вернулся к документу и рассмотрел второй способ ведения дел, то есть создание AST. Теперь, если я чего-то не вижу, ничто не объясняет вам, как взять созданный вами AST и подключить его так, чтобы Psych.dump(obj) все еще работал…
Я пытался сделать (без особой надежды):
a = Psych::Nodes::Scalar(full_address.upcase)
a.style = Psych::Nodes::LITTERAL
coder['address'] = a if full_address?
но, очевидно, он не сделал того, на что я надеялся… Я также пробовал:
def encode_with(coder)
Psych::Nodes::Mapping.new.tap do |map|
map.children << Psych::Nodes::Scalar.new("name")
map.children << Psych::Nodes::Scalar.new(name)
map.children << Psych::Nodes::Scalar.new("address")
a = Psych::Nodes::Scalar.new(full_address.upcase)
a.style = 4
map.children << a
end
end
Но я не мог понять, как подключить его к кодеру…
Кроме того, ответ должен работать при выполнении рекурсивных действий, это объект Contact
, но можно попросить Domain
, который будет содержать несколько контактов, и я хочу, чтобы он был как можно СУХИМ :-)
Итак, у кого-нибудь есть намек на то, как это сделать?