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,

メソッドの呼び出しはすでに終わっているのに、変数が保持されているのがおもしろくもあり、不思議でもありですね。