前田です。 中村暁史 <anakamur / exa.i-tech.co.jp> writes: > MarshalってdelphiのTWriterおよびTReaderを強力にしたような奴 > だと思って、イイのですよね? > delphiの(デフォの)だと専用バイナリフォーマットでしか出し入れしない > みたいだ、という意味で。 TWriter/TReaderって何でしたっけ。 > 永続化するかどうかの制御はどーすんのかな?と説明書を読みます…読みます… > Marshalに読み書きさせたくない属性を自分のobjectに持たせたいと思ったら、 > その属性をdataとかのMarshal非対応オブジェクトにすればいい、って > ことでしょうか? RubyにはJavaのtransientみたいなものはないので、そういう時には_dump/_load を自前で定義してやらないといけません。 class Person attr_reader :name, :age attr_accessor :nickname def initialize(name, age) @name = name @age = age @nickname = nil end # Personを文字列化するためのメソッド def _dump(limit) # @name, @ageのみ保存 return Marshal::dump([@name, @age], limit) end # 文字列からPersonオブジェクトを復元するメソッド def Person._load(str) # loadしたデータを引数にしてコンストラクタを起動 return new(*Marshal::load(str)) end end mick = Person.new("Michael", 23) mick.nickname = "Mick" p mick.name #=> "Michael" p mick.age #=> 23 p mick.nickname #=> "Mick" s = Marshal::dump(mick) person = Marshal::load(s) p person.name #=> "Michael" p person.age #=> 23 p person.nickname #=> nil 上の例でPersonは@name,@age,@nicknameというインスタンス変数を持ちますが、 marshalingした時に@nicknameは保存されないようにしてあります。 しかし、実際にこれをruby 1.3.1(99/02/10)で実行すると落ちます:-( どうやらバグみたいなので別メールでパッチを送ります。 class Person transient :nickname ... end みたいに保存しないインスタンス変数を指定できると便利かもしれませんね。 -- 前田 修吾 (mailto:shugo / netlab.co.jp)