From: m_seki@... Date: 2003-10-12T00:43:54+09:00 Subject: [ruby-list:38508] Re: marshal_dump (was Re: ) 咳といいます。BMarshal(ABLoad)を思い出してきた… > In message "[ruby-list:38486] Re: marshal_dump (was Re: )" > on 03/10/09, Masatoshi Seki writes: > > |サブクラスはどうやって救えばいいんだろう。 > |かっこいい方法ないですかねえ。 > > 今みたいな簡単な方法ではなくて、dumperクラスのようなものを用 > 意して、それの各メソッド(インスタンス変数のダンプとか)をオー > バーライドしてカスタマイズするのがかっこいいとは思います。が、 > 今のMarshalとの互換性は維持できないでしょうね。 よくある使い方は、 * 特別なインスタンス変数を出力しない、あるいは、 別の値を出力する だと思います。 そこで、デフォルトで全部のインスタンス変数を保持したオブジェクト (たとえばHash)を返すようにして、カスタマイズする方で出力しない、 または別の値に取り替えるように調整するのはどうでしょう? [ruby-dev:21590]のextendの件はmarshal.cで気を使ってくれると 良いように思うけど、どうなのかしら。 class Object def default_marshal_dump desc = {} instance_variables.each do |name| desc[name] = instance_variable_get(name) end desc end def default_marshal_load(desc) desc.each do |name, value| next unless String === name next unless name[0] == ?@ instance_variable_set(name, value) end end end class Foo def initialize @data_a = 1 @r, @w = IO.pipe end def marshal_dump desc = default_marshal_dump desc.delete('@r') desc.delete('@w') desc end def marshal_load(desc) default_marshal_load(desc) @r, @w = IO.pipe end end class Bar < Foo def initialize super @data_b = 2 end end o1 = Bar.new o2 = Marshal.load(Marshal.dump(o1)) p o1 p o2 marshal.cがObject#marshal_dumpがあってもカスタマイズと思わないで くれるようにできれば、Object#default_marshal_dumpは、marshal_dumpに 改名して、Foo#marshal_dumpからは desc = super と呼びたいところです。 Rubyのプリミティブや拡張ライブラリで、インスタンス変数ではない なにかを持ってるなら、desc[:primitive]とかにしまうようにするとか‥ Structもなにかしないとだめかも。