なかだ さん、こんにちは。

速攻(即効)での回答ありがとうございます。

> finalizerが呼ばれる時点では対象のオブジェクトはすでに破棄されて
> いるのでインスタンス変数としてはアクセスできませんが、finalizer
> から参照される限りインスタンス変数だったオブジェクト自体はまだ
> 生きていますから、アクセス可能です。

この意味理解できます。
> 
>   class C
>     attr_accessor :data
>     def self.save_data_proc(data, dirty, file)
>       proc do
>         if dirty[0]
>           open(file, "w") {|f| Marshal.dump(data, f)}
>         end
>       end
>     end
>     def initialize(*data)
>       @data = data
>       @dirty = [false]
>       fin = self.class.save_data_proc(@data, @dirty, "saved.data")
>       ObjectSpace.define_finalizer(self, fin)
>     end
>     def dirty?
>       @dirty[0]
>     end
>     def dirty=(d)
>       @dirty[0] = d
>     end
>   end

これとよく似たコードを作ったつもりでしたが、上手くいかない部分が
ありました。でなにが違うか検討してから再度連絡します。

クラスメソッドを定義する際に名前を埋め込まない場合は上記のようにする
のですね、参考にします。

元の質問とは直接関係しませんが、コードに関する追加の質問です。
1.@dirtyは単にデータが変更されたことを示すフラグとして利用しているだ
け?
2.@dirtyが配列として定義している意味は?

宜しくお願いします。