Хорошо, так что, прежде всего, добро пожаловать в замыкания:)
Замыкание - это фрагмент кода, который вы можете передавать как переменную, это простая часть. Другая сторона заключается в том, что замыкание поддерживает область, в которой оно было вызвано.
Что на самом деле происходит, так это то, что, когда вы храните свои процы, каждый берет ссылку на n. несмотря на то, что вы выходите за рамки цикла for, эта ссылка на n по-прежнему остается неизменной, и каждый раз, когда вы выполняете свои процессы, они выводят окончательное значение n. Проблема здесь в том, что каждая итерация не в своей области видимости.
То, что Адриан предложил сделать, это поменять цикл for на блок range.each. Разница в том, что каждая итерация имеет свою собственную область, и это то, что связано с процедурой
$bar = []
(0..15).each do |i|
#each i in here is local for this block
$bar[i] = Foo.new
$bar[i].setmyproc { puts i }
end
Это действительно не простая вещь, чтобы обернуть вашу голову, но это одна из тех вещей, которые будут продолжать сбивать вас с толку, пока вы действительно не получите это. Я, вероятно, проделал ужасную работу, объясняя это, если бы он не превращался в гель, я потратил бы немного времени на поиски работы затворов с областью действия.