なひです。 > From: <m_seki / mva.biglobe.ne.jp> > Sent: Sunday, October 12, 2003 12:43 AM > > |サブクラスはどうやって救えばいいんだろう。 > > |かっこいい方法ないですかねえ。 > > 今みたいな簡単な方法ではなくて、dumperクラスのようなものを用 > > 意して、それの各メソッド(インスタンス変数のダンプとか)をオー > > バーライドしてカスタマイズするのがかっこいいとは思います。が、 > > 今のMarshalとの互換性は維持できないでしょうね。 なひはいまひとつ、このまつもとさん提案の方法が、どのようにサブクラスを 救うのか理解できてません。。。 ちなみにJavaでは、dumperが、クラス階層内の各クラスの writeObjectメソッドをそれぞれ呼んでくれるので(2種類あるserialize インタフェイスの手軽なほう)、各クラスが、自分で定義した インスタンス変数(とは呼ばないけど)を書き出すことで、救えます。 writeObjectメソッドが定義されてない場合、デフォルトで全ての インスタンス変数(同)が書き出されます。 Rubyでもmarshal_dumpを順に呼べないかな、という試みを、 [ruby-dev:21590]あたりでやってみています。うまくいってないんだけど。 > よくある使い方は、 > * 特別なインスタンス変数を出力しない、あるいは、 > 別の値を出力する > だと思います。 > > そこで、デフォルトで全部のインスタンス変数を保持したオブジェクト > (たとえばHash)を返すようにして、カスタマイズする方で出力しない、 > または別の値に取り替えるように調整するのはどうでしょう? Rubyでは、インスタンス変数がどのクラスで定義されているか、 あまり意識してない人が多いような気がします(?)。よって咳さんの 書かれてるように、Javaみたいにクラス階層をたどることで債務分割を するのでなく、一番下位のmarshal_dump/marshal_loadを定義するヤツが 気をつけて全部やれ、とするのもアリだと思います。 ただこうした時の問題は、継承する側は、親クラスが marshal_dump/marshal_loadを定義してないかどうか常に気をつけないと いけない、ということであり、JavaのようにSerializableインタフェイスという マーカなしにdumpできるRubyでは、それ(気をつけないといけないこと)に 気付きにくいということですね(Timeを継承したクラスで_dumpを定義し 忘れておかしなことになったように)。 > [ruby-dev:21590]のextendの件はmarshal.cで気を使ってくれると > 良いように思うけど、どうなのかしら。 ivarsはやらないんだからextendsもやらない、というのは、仕様がすっきり してていいと思うんですよね。ただ、[ruby-dev:21592]からのように、 回避方法がないと、どうしても困る場面もでてくるかもしれません (根拠はありません。誰も困らないかも)。 / / / 関連してひとつ、別の提案ですが、Javaでは、とあるメソッド(readResolve)を 定義しておくと、loadの後に呼んでくれて、そいつが返したオブジェクトを元の オブジェクトとすりかえる、という機能があります。singletonやenumな クラスで、loaderが生成した新規オブジェクトを、singletonオブジェクトと すりかえられます。 こんなのはRubyには要りませんかね?