Ruby 心理医生说«;中层正在建设一个AST&x2026»;但是,具体如何?
我使用Ruby 心理医生说«;中层正在建设一个AST&x2026»;但是,具体如何?,ruby,string,yaml,psych,Ruby,String,Yaml,Psych,我使用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?
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)仍然可以工作的方式插入它
我试着做(没有多大希望):
但是,很明显,它没有达到我希望的效果……我也尝试过:
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
def encode_与(编码器)
Psych::Nodes::Mapping.new.tap do | map|
map.children如果要创建自己的AST,则不能使用Psych.dump
Psych.dump
使用Psych默认值创建自己的AST。在您的情况下,您希望自定义AST创建过程
查看,您可以看到它使用创建AST。您可以将其子类化,并自定义它如何处理您的Contact
类,以获得所需的输出。特别是,您需要覆盖
下面是一个简单的示例,仅用于联系人
类的特殊情况:
class MyYAMLTree < Psych::Visitors::YAMLTree
def accept target
return super unless target.is_a? Contact
@emitter.start_mapping(nil, "tag:yaml.org,2002:#{target.class}", false, Psych::Nodes::Mapping::BLOCK)
@emitter.scalar 'name', nil, nil, true, false, Psych::Nodes::Scalar::ANY
@emitter.scalar target.name, nil, nil, true, false, Psych::Nodes::Scalar::ANY
@emitter.scalar 'address', nil, nil, true, false, Psych::Nodes::Scalar::ANY
#this is the where we make the address string a literal
@emitter.scalar target.full_address, nil, nil, true, false, Psych::Nodes::Scalar::LITERAL
@emitter.end_mapping
end
end
这显然只是一个简单的例子,但希望它能为您指明正确的方向。您指的是Syck,而不是Sych,就像原始库一样,对吗?
class MyYAMLTree < Psych::Visitors::YAMLTree
def accept target
return super unless target.is_a? Contact
@emitter.start_mapping(nil, "tag:yaml.org,2002:#{target.class}", false, Psych::Nodes::Mapping::BLOCK)
@emitter.scalar 'name', nil, nil, true, false, Psych::Nodes::Scalar::ANY
@emitter.scalar target.name, nil, nil, true, false, Psych::Nodes::Scalar::ANY
@emitter.scalar 'address', nil, nil, true, false, Psych::Nodes::Scalar::ANY
#this is the where we make the address string a literal
@emitter.scalar target.full_address, nil, nil, true, false, Psych::Nodes::Scalar::LITERAL
@emitter.end_mapping
end
end
def my_yaml o
visitor = MyYAMLTree.new
visitor << o
visitor.tree.yaml
end