10

例えば、

class Point
  attr_accessor :x, :y, :pointer_to_something_huge
end

x と y のみをシリアル化し、それ以外はすべて nil のままにします。

4

6 に答える 6

24

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

デフォルトでは、Yaml からロードするときに新しいオブジェクトの対応するインスタンス変数を適切な値に設定するため、この場合はこれで十分ですが、より複雑なケースでは次のように使用できますinit_with

def init_with coder
  @x = coder['x']
  @y = coder['y']
end
于 2012-05-17T22:17:54.127 に答える
8

膨大な量の検索の後、私はこれに出くわしました:

class Point
  def to_yaml_properties
    ["@x", "@y"]
  end
end

このメソッドは、YAML がシリアル化するプロパティを選択するために使用されます。(Psych で) カスタム エミッターを使用するより強力なアプローチがありますが、それが何であるかはわかりません。

このソリューションは Ruby 1.8 でのみ機能します。Ruby 1.9では、to_yamlPsychの使用に切り替えました.Psychの使用encode_withが適切な解決策です.

于 2012-05-17T12:37:56.787 に答える
1

インスタンス変数がたくさんある場合は、このような短いバージョンを使用できます

def encode_with( coder )
  %w[ x y a b c d e f g ].each { |v| coder[ v ] = instance_variable_get "@#{v}" }
end
于 2014-05-14T19:47:57.727 に答える
1

いくつかのフィールドを除くすべてのフィールドが必要な場合は、これを行うことができます

def encode_with(coder)
  vars = instance_variables.map{|x| x.to_s}
  vars = vars - ['@unwanted_field1', '@unwanted_field2']

  vars.each do |var|
    var_val = eval(var)
    coder[var.gsub('@', '')] = var_val
  end
end

これにより、手動でリストを管理する必要がなくなります。Ruby 1.9 でテスト済み

于 2014-05-13T19:54:12.890 に答える
-2

必要な特定の yaml 形式を構築するカスタムto_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

optsそのため、yaml に特定のキーと値のペアを含めるように設定する機会があるようです。

于 2012-05-17T03:01:56.137 に答える