例えば、
class Point
attr_accessor :x, :y, :pointer_to_something_huge
end
x と y のみをシリアル化し、それ以外はすべて nil のままにします。
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
膨大な量の検索の後、私はこれに出くわしました:
class Point
def to_yaml_properties
["@x", "@y"]
end
end
このメソッドは、YAML がシリアル化するプロパティを選択するために使用されます。(Psych で) カスタム エミッターを使用するより強力なアプローチがありますが、それが何であるかはわかりません。
このソリューションは Ruby 1.8 でのみ機能します。Ruby 1.9では、to_yaml
Psychの使用に切り替えました.Psychの使用encode_with
が適切な解決策です.
インスタンス変数がたくさんある場合は、このような短いバージョンを使用できます
def encode_with( coder )
%w[ x y a b c d e f g ].each { |v| coder[ v ] = instance_variable_get "@#{v}" }
end
いくつかのフィールドを除くすべてのフィールドが必要な場合は、これを行うことができます
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 でテスト済み
必要な特定の 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 に特定のキーと値のペアを含めるように設定する機会があるようです。