扩展Hash和(de)序列化从/到yaml

时间:2011-09-11 10:25:22

标签: ruby hash yaml

我找到了这个例子: http://www.yaml.org/YAML_for_ruby.html#extending_kernel::hash

很高兴看到YAML可以轻松地序列化哈希。 但是,我想序列化我自己的类,一个带有该属性的扩展哈希。

yaml-string的外观是什么,序列化的最佳方式是什么?

提前致谢

2 个答案:

答案 0 :(得分:2)

您可以使用原始Hash#to_yaml的{​​{3}}并覆盖它,添加您需要的任何内容:

def to_yaml( opts = {} )
  YAML::quick_emit( self, opts ) do |out|
    out.map( taguri, to_yaml_style ) do |map|
      # here you can add something like:
      map.add('my_attribute', @my_attribute)
      # and proceed with the usual Hash serialization:
      each do |k, v|
        map.add( k, v )
      end
    end
  end
end

答案 1 :(得分:1)

正如MladenJablanović的回答所示,你可以覆盖to_yaml。你可以添加一个名为'attributes'的数组(如果哈希中有一个带有该名称的密钥,则要特别注意转义该名称(如果......等等,请注意转义转义的名称))。但是,您需要一些内部知识才能使这项工作成为可能(out.map(tag_uri, to_yaml_style)及其变体是非常重要的,并且没有详细记录:各种Ruby解释器的来源是您最好的选择。)

不幸的是,您还需要覆盖反序列化过程。如何重用现有代码几乎完全没有文档。与this answer中一样,您会看到需要添加to_yaml_type并使用YAML::add_domain_type添加反序列化代码。从那里开始,你几乎都是自己的:你需要编写半个YAML解析器来解析所有的字符串并将其转换为你的对象。

有可能弄清楚,但是我上次想要的更简单的解决方案就是让Hash成为我对象的属性,而不是扩展Hash。后来我意识到我实际上并没有实现Hash的子类。存储键值对的东西并不一定意味着哈希。如果您实施:[]:[]=each,您通常可以将对象视为哈希。