如何控制使用YAML序列化的字段

ale*_*loh 9 ruby yaml

例如,

class Point
  attr_accessor :x, :y, :pointer_to_something_huge
end
Run Code Online (Sandbox Code Playgroud)

我只想序列化x和y并将其他所有内容保留为nil.

mat*_*att 23

在Ruby 1.9中,to_yaml_properties不推荐使用 ; 如果您使用的是Ruby 1.9,则可以使用更具前瞻性的方法encode_with:

class Point
  def encode_with coder
    coder['x'] = @x
    coder['y'] = @y
  end
end
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这就是您所需要的,因为默认情况下是从Yaml加载时将新对象的相应实例变量设置为适当的值,但在更完整的情况下,您可以使用init_with:

def init_with coder
  @x = coder['x']
  @y = coder['y']
end
Run Code Online (Sandbox Code Playgroud)


ale*_*loh 8

经过大量的搜索,我偶然发现了这个:

class Point
  def to_yaml_properties
    ["@x", "@y"]
  end
end
Run Code Online (Sandbox Code Playgroud)

此方法用于选择YAML序列化的属性.有一种更强大的方法涉及自定义发射器(在Psych中),但我不知道它是什么.

此解决方案仅适用于Ruby 1.8; 在Ruby 1.9中,to_yaml已经转向使用Psych,Matt使用的答案encode_with是适当的解决方案.


Kev*_*ell -2

我建议to_yaml在您的类中添加一个自定义方法来构造您想要的特定 yaml 格式。

我知道它to_json接受参数来告诉它要序列化哪些属性,但我找不到相同的to_yaml.

这是实际来源to_yaml

# File activerecord/lib/active_record/base.rb, line 653

  def to_yaml(opts = {}) #:nodoc:
    if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck?
      super
    else
      coder = {}
      encode_with(coder)
      YAML.quick_emit(self, opts) do |out|
        out.map(taguri, to_yaml_style) do |map|
          coder.each { |k, v| map.add(k, v) }
        end
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

因此,看起来可能有机会进行设置,opts以便在 yaml 中包含特定的键/值对。