gpt4 book ai didi

ruby - 强制 Psych 读取 YAML 映射作为给定类的对象

转载 作者:数据小太阳 更新时间:2023-10-29 07:52:16 24 4
gpt4 key购买 nike

我有一个类 Foo 应该以最人性化的方式序列化为文本文件,我使用 Ruby 的默认 YAML(Psych) 和自定义 encode_with。我的问题是:如果我像这样删除 !ruby/object:Foo:

def encode_with coder
coder.tag = nil
...
end

我能否以某种方式强制 Psych 将 map 加载为类 Foo 的对象(使用其 init_with)。理想情况下,我也想删除 --- 文档标记。

当然,这很容易用 gsub 解决,但我想知道是否有一些 Psych 解决方案。不幸的是,Psych 并不是最好的 gem 记录。

最佳答案

您可以向 Psych 提供自己的 Handler:

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 default parse method 的重新实现.而不是 default handler我在这里使用 MyHandler

MyHandlerstart_mapping 方法覆盖了 TreeBuilderdefault implementation .这是一个回调,当解析器在 YAML 中遇到 Map 时调用,并且文档根一个 Map。因此,您只需将标签替换为根元素(不要为其他任何事情操心——这就是为什么我使用 @__root 变量来跳过进一步的修改)。

关于ruby - 强制 Psych 读取 YAML 映射作为给定类的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32104842/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com