You know, I think that the original post should have worked, as long
as the iterator variable wasn't previously declared in the same scope
as the iterator. This works:
procs = []
[1, 2, 3].each { | x | procs << Proc.new { puts x } }
procs.each { | p | p.call }
# prints 1, 2, 3
If the iterator variable was used previously then the iterator updates
the existing variable instead of creating a new lexically scoped one
each time through the loop:
x = nil
procs = []
[1, 2, 3].each { | x | procs << Proc.new { puts x } }
procs.each { | p | p.call }
# prints 3, 3, 3
So it seems that the procs ought to have worked -- as long as there
wasn't a previously declared variable of the same name.
I'm wondering if the problem wasn't that the "window" and "image"
methods lacked a proper context when the procs were called. That
seems to be a much more likely place for problems to arise. (The
"Rules of Shoes" section of the manual aids in navigation through the
hairiness.)
On Jul 27, 2009, at 5:15 AM, MenTaLguY wrote:
I wasn't terribly clear. Let me rephrase -- if you do this:
urls.each do |url|
link url, :click => Proc.new { window { image url } }
end
Then every link will open the same image url (since all the created
Procs reference the same variable, which ends up with the same final
value). However, if you do this:
def make_image_callback(url)
Proc.new { window { image url } }
end
image_urls.each do |image_url|
link image_url, :click => make_image_callback(image_url)
end
Then the links should open the correct images, since each call to
make_image_callback establishes up a separate context for a Proc
inside
to capture, rather than all the Procs sharing the same context and
variables.
You could also do the call to link itself inside the helper method
(as I
did in my earlier email), but you don't need to.
-mental