Procと変数
Procオブジェクトはコンテキストを保持します。
ですから、外部でローカル変数が書き換えられると、Procオブジェクトの中で参照していた変数の値も変化します。
n = 123 p = proc { puts n } p.call #=> 123 n = 456 p.call #=> 456 def rubyco(p, n) p.call end rubyco(p, 789) #=> 456
メソッド呼び出しでは、ローカル変数が毎回生成されますから、別のコンテキストが保持されることになります。
def func(x) n = x return proc { puts n } end x = func(123) x.call #=> 123 y = func(456) y.call #=> 456 x.call #=> 123
再帰呼び出しでも、その時点でのローカル変数がきちんとコンテキストとして保持されます。
def rubyco(ary, index) if index >= 0 ary[index] = proc { print "#{index}, " } rubyco(ary, index - 1) ary end end a = rubyco(Array.new, 10) (0..10).each { |i| a[i].call } #=> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
メソッドの呼び出しはすでに終わっているのに、変数が保持されているのがおもしろくもあり、不思議でもありですね。