From: "西 啓一朗" Date: 2002-07-23T20:35:19+09:00 Subject: [ruby-dev:17779] Re: self in block どうも、初めての発言です。西啓一朗@Ktouth Brand. です。 この議論、興味深く読ませてもらってましたが、ちょっと気になったので質問さ せてください。 class Sample def initialize(&block) @proc = block end end obj = Sample.new { n==0 ? 1:n*self[n-1]} func = Proc.new { n==0 ? 1:n*self[n-1]} obj2 = Sample.new &func obj3 = Sample.new &func まず、上のコード例でのブロックの実際の処理ですが.... (0. 実行前に構文木にコンパイルされている) 1. ブロック指定子「{」にさしかかる(=ブロック部分の構文木を参照する)と、 Procクラスのインスタンスの生成が行われる。 1a. このインスタンスには「ブロック部分の構文木への参照」と「ブロックで必 要になるブロック外のオブジェクトへの参照」が保持されている。 1b. この参照の中には、コード内に出てきたselfに対応するオブジェクトの参照 も含む。(メソッド呼び出しやインスタンス変数参照にも必要なので) 2. 生成したProcクラスのインスタンスを引数としてSample.newが呼ばれる。 ....という理解で合っていますでしょうか? 合ってないなら、この質問は聞き流してください^^; で、正木さんのselfすげ替え案で実装されたと仮定したとき、Procインスタンス のselfに対応するオブジェクトを差し替えることになるわけだから、Procの中で もSampleインスタンスが参照されているために循環参照が発生し、ガベージでき ないオブジェクトになっちゃいませんか? この推測が間違ってないなら、メモリリークに相当するバグになる気がします。 対して、ProcクラスのインスタンスのProc#callを呼び出している間だけ、selfすげ替えが 機能するのなら、デフォルトですげ替えるのではなく、もっと単純に Proc#call_by(obj, *prm) のようなメソッドが追加されれば十分な気がしますが……どうでしょう? -- 西 啓一朗