The "for" construct doesn't create a new scope, so the "resource"
variable is the same for all iterations. The closure created by the
do..end block passed to the get method closes on just a single
variable "resource". So when later the block is executed, both blocks
have the same value of "resource", which is the one from the last
iteration. Check this:
irb(main):007:0> procs = []
=> []
irb(main):008:0> for s in %w{a b c}
irb(main):009:1> procs << lambda {puts s}
irb(main):010:1> end
=> ["a", "b", "c"]
irb(main):011:0> procs.each {|x| x[]}
c
c
c
The "each" method, on the other hand gets passed a regular block,
which creates a new local scope. In that case each iteration creates a
new variable "resource", so that each do...end block closes on a
*different* variable "resource". Check:
irb(main):022:0> procs = []
=> []
irb(main):023:0> %w{a b c}.each do |string|
irb(main):024:1* procs << lambda {puts string}
irb(main):025:1> end
=> ["a", "b", "c"]
irb(main):026:0> procs.each {|x| x[]}
a
b
c
Also note, that (at least in 1.8), if a variable with the same name as
the block parameter exists, the above doesn't hold, and the block
parameter is again the same for all iterations:
irb(main):027:0> string = "something"
=> "something"
irb(main):028:0> procs = []
=> []
irb(main):029:0> %w{a b c}.each do |string|
irb(main):030:1* procs << lambda {puts string}
irb(main):031:1> end
=> ["a", "b", "c"]
irb(main):032:0> procs.each {|x| x[]}
c
c
c
I think this has changed in 1.9, so that local variables and block
parameters are independent, but I can't test it right now.
Hope this helps,
Jesus.