Threads and parameters bug (?)

I wrote this program

threads = []
for i in 1…3
threads << Thread.new(i) { |i|
sleep(i)
print i
}
end
threads.each { |aThread| aThread.join }

I expected to see: 123
but I got : 333

Is it a bug? or is it normal?
To my mind it might be a bug because the code doesn’t do what it seems to
do.(?)

Upon to me the ‘i’ variable of the ‘print i’ should be ‘|i|’ (which is the
last declaration of ‘i’) and not the ‘i’ in ‘for i in 1…3’ (which value is
’3’ and the end of the loop).

Can anybody explain me?
Thanks

Ps:
Of course if I write
for i in 1…3
threads << Thread.new(i) { |a|
sleep(1)
print a
}
it works.

for i in 1..3
  threads << Thread.new(i) { |i|

[...]

I expected to see: 123
but I got : 333

Is it a bug? or is it normal?

it's normal : the 3 threads share the same variable `i' and this is the
varible in `for'

Upon to me the 'i' variable of the 'print i' should be '|i|' (which is the
last declaration of 'i') and not the 'i' in 'for i in 1..3' (which value is
'3' and the end of the loop).

wait for ruby 2

Guy Decoux

“ts” decoux@moulon.inra.fr schrieb im Newsbeitrag
news:200312151626.hBFGQV102470@moulon.inra.fr

for i in 1…3
threads << Thread.new(i) { |i|
[…]
I expected to see: 123
but I got : 333

Is it a bug? or is it normal?

it’s normal : the 3 threads share the same variable i' and this is the varible in for’

Upon to me the ‘i’ variable of the ‘print i’ should be ‘|i|’ (which
is the
last declaration of ‘i’) and not the ‘i’ in ‘for i in 1…3’ (which
value is
‘3’ and the end of the loop).

wait for ruby 2

There’s another easy fix: change the name of the variable you use inside
the block. The original version was effectively equivalent to this:

threads =
for i in 1…3
threads << Thread.new {
sleep(i)
print i
}
end
threads.each { |aThread| aThread.join }

Now the meaning of the Thread constructor args becomes visible:

threads =
for i in 1…3
threads << Thread.new(i) { |j|
sleep(j)
print j
}
end
threads.each { |aThread| aThread.join }

Will print the expected “123”.

Kind regards

robert