问题描述
我有一个类 Foo
应该以最人性化的方式序列化为文本文件,我使用 Ruby 的默认 YAML(Psych) 和自定义 encode_with
.我的问题是:如果我像这样删除 !ruby/object:Foo
:
I have a class Foo
that is supposed to be serialized to a text file in most human-friendly way possible, I use Ruby's default YAML(Psych) with custom encode_with
. My question is: if I remove !ruby/object:Foo
like so:
def encode_with coder
coder.tag = nil
...
end
我还能以某种方式强制 Psych 加载地图作为 Foo
类的对象(使用它的 init_with
).理想情况下,我也想删除 ---
文档标记.
can I somehow still force Psych to load a map as object of class Foo
(using its init_with
). Ideally, I'd like to remove ---
document mark as well.
当然,用gsub
很容易解决这个问题,但我想知道是否有一些Psych解决方案.不幸的是,Psych 并不是关于宝石的最佳记录.
Of course, this is easy to solve with gsub
, but I wonder if there is some Psych solution for this. Unfortunately, Psych isn't the best documented of gems.
推荐答案
您可以向 Psych 提供您自己的 Handler
:
You can provide your own Handler
to Psych:
class MyHandler < Psych::Handlers::DocumentStream
def start_mapping(anchor, tag, implicit, style)
unless @__root
tag = "!ruby/hash:MyHash"
@__root = true
end
super anchor, tag, implicit, style
end
end
class MyHash < Hash
end
def my_parse(yaml)
parser = Psych::Parser.new(MyHandler.new{|node| return node})
parser.parse yaml
false
end
# {a: 1, b: {c: 2, d: 3}, c: [1,2,3]}.to_yaml
str = "---\n:a: 1\n:b:\n :c: 2\n :d: 3\n:c:\n- 1\n- 2\n- 3\n"
result = my_parse(str).to_ruby
puts result.class # => MyHash
一些文档.my_parse
只是 Psych 默认解析方法.我使用 MyHandler默认处理程序/code> 在这里.
A bit of documentation. my_parse
is just a re-implementation of Psych default parse method. Instead of default handler I use MyHandler
here.
MyHandler
的 start_mapping
方法覆盖了 TreeBuilder
的 默认实现.这是一个回调,当解析器遇到 YAML 中的 Map 时调用,文档根是一个 Map.所以你只需要交换根元素的标签(不要打扰其他一切——这就是为什么我使用 @__root
变量来跳过进一步的修改).
MyHandler
's start_mapping
method overrides TreeBuilder
's default implementation. This is a callback which is called when parser bumps into Map in YAML, and document root is a Map. So you just need to swap the tag for the root element (and don't bother with everything else – that's why I use @__root
variable to skip further modifications).
这篇关于强制 Psych 将 YAML 映射读取为给定类的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!