我有一个 Foo
类,它是 Hash
的子类。
class Foo < Hash
# whatever Foo-specific methods/etc
end
当我使用 YAML 将它转储到一个文件时,它被写入一个指示类的标签。
> f = Foo.new
> f[:bar] = "baz"
> puts YAML.dump(f)
--- !ruby/hash:Foo
:bar: baz
我希望它只是写成一个普通的旧散列(不是 !ruby/hash:Foo
)
> puts YAML.dump({bar:"baz"})
---
:bar: baz
...这样我的数据的消费者就不需要了解 Foo
。是否有一种神奇的方法可以添加到我的类中以将其自身转换为序列化,或者是否有一种神奇的选项可以传递给 YAML.dump?
当然,将一个 Foo
对象转换为散列很容易,但它们可能嵌套在我想转储的实际散列中的任何级别,我宁愿不转储必须进行搜索和替换。
最佳答案
您可以使用(记录不完整的)encode_with
和 represent_map
方法来实现这一点。要自定义对象的 YAML 序列化,您可以为其提供 encode_with
方法,该方法接受 coder
。对象,其中一种方法是 represent_map
.
class Foo < Hash
# other methods ...
def encode_with coder
coder.represent_map nil, self
end
end
现在 YAML.dump
只会将您的对象输出为普通散列。
但是
有一点问题,因为有一个错误会导致失败并且是 only fixed in the latest Gem version of Psych .它在当前最新的 Ruby 版本 (ruby 2.0.0p247) 中未得到修复。它is fixed in Ruby trunk所以以后的补丁发布应该没问题。
为了使用它,您必须确保您使用的是最新的 Psych Gem,而不是与 Ruby 捆绑在一起的版本。这应该很简单
gem 'psych', '2.0.0'
在你需要 Yaml 之前,但在 Ruby 2.0 中,由于某种我无法弄清楚的原因,这似乎不起作用。不过,使用 Bundler 指定 Gem 版本确实可行,因此您可能需要创建一个 Gemfile
并在其中指定 Psych(如果您尚未使用它)。
关于ruby - 我如何让 Ruby YAML 将 Hash 子类转储为简单的 Hash?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18178098/