我有这个旧代码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 服务器的输出,而且人类可读性较差……</p>
于是,我又回到了 doc,看了一下第二种做事方式,也就是构建 AST。现在,除非我什么都没看到,否则没有什么可以解释如何获取您构建的 AST,并将其插入 Psych.dump(obj) 仍然可以工作的方式......</p>
我试着做(没有太大希望):
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包含一些联系人的对象,我希望它尽可能 DRY :-)
那么,有人对如何做到这一点有提示吗?