i = 0
while i < 10
_i = i
spawn do
puts(_i) # <= the variable _i is not a shared variable, right?
end
i += 1
end
Fiber.yield
On my laptop, the output is:
╰─ $ 1 cr 1.cr
9
9
9
9
9
9
9
9
9
9
i = 0
while i < 10
_i = i
spawn do
puts(_i) # <= the variable _i is not a shared variable, right?
end
i += 1
end
Fiber.yield
On my laptop, the output is:
╰─ $ 1 cr 1.cr
9
9
9
9
9
9
9
9
9
9
while
does not create a new scope. So _i
is closured and shared within the entire top-level scope.
A block creates a new scope, so this program would have the desired effect:
10.times do |i|
_i = i
spawn do
puts(_i)
end
end
Fiber.yield
EDIT: I removed an completely unnecessary begin ... end
block which wasn’t supposed to be in the example.
That’s why you can also do spawn puts(i)
It does all the boilerplate that @straight-shoota just typed.
There’s also a section in the reference book that I linked to that explains/suggests using spawn puts(i)
. Tho it seems my link gets collapsed down to make it look like i’m just linking to the concurrency docs suggesting “go look it up yourself” .
Thanks, @Blacksmoke16 , in fact, I have read these documents before.
what i expected answer is @straight-shoota 's this answer, it made me understand why.
i just remember that in some languages, golang? when assign the loop pushed variable into a local variable, can avoid this issue, that is way i add a _i = i
within the while loop, there is no example in the linked document explain this.
Actually Go has the same issue: redefining for loop variable semantics · Discussion #56010 · golang/go · GitHub
With a block you don’t need to assign the variable to another variable. That’s another advantage of blocks. No need for that _i in your example.
I guess another advise is: try to use idiomatic code like looping over ranges, 10.times, etc. Try to avoid while, especially because there are many abstractions over it. While can be considered a low level primitive.
Yes, in fact, following code works.
10.times do |i|
spawn do
puts(i)
end
end
Fiber.yield
But, following code not work. because begin ... end
not create a new scope too.
i = 0
while i < 10
begin
_i = i
spawn do
puts(_i)
end
i += 1
end
end
Fiber.yield