ruby - 我如何让 Ruby YAML 将 Hash 子类转储为简单的 Hash?

标签 ruby hash yaml

我有一个 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_withrepresent_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/

相关文章:

ruby - 如何在停止时杀死 ruby​​ Thor 中的所有进程?

c++ - 遇到某个词时停止文件输入

python - 在单元测试中提取哈希种子

azure-devops - 检查 Azure YAML 中的空对象类型参数

yaml - Python : Read information from . yaml

Ruby 数组映射(& :flatten) is causing a latency issue

javascript - AngularJS 不会将新记录推送到数组中

ruby - Chef Recipe 中的无效多字节字符 (US-ASCII)

c# - Windows 哈希密码

Python包: Can I look for config/yml file from project directory which called it?