Using variables outside of anonymous functions

I encountered an interesting issue. I will just show it instead of trying to explain.

local q = {}--short for queue
local c = 0--short for count
local max = 4
for x = 1, max  do
    for y = 1, max do
        c = c + 1 
        q[c] = function() print(c.."/"..max^2, x, y) end

    end
end

for f = 1, #q do
    q[f]()
end

The anonymous functions should print their count out of all of them. I expected
1/16 1 1
2/16 1 2


instead, this results in
16/16 1 1
16/16 1 2

As in, count is always 16. I am guessing this is because it is retrieving the variable after it has been upped all the way to 16. However, as you can see x and y are okay, which confuses me.
Can somebody explain this and is there any other way to get the ‘correct’ result besides passing a parameter into the functions (such as passing f to serve as c)? I use this technique on a larger scale and passing parameters is not going to be nice.

x and y are local to your loop, but c is outside. This means that every function call will reference the same c. When x = 1, then all table entries created during that loop will reference that, then the same for x = 2, etc.

A fairly simple way to solve this is to just create a new local c inside the loop, e.g.

local q = {}--short for queue
local c = 0--short for count
local max = 4
for x = 1, max  do
    for y = 1, max do
        c = c + 1
        local c = c -- creates a new c local to this scope.
        q[c] = function() print(c.."/"..max^2, x, y) end
    end
end

for f = 1, #q do
    q[f]()
end
2 Likes

thanks that worked!