Forgive this perhaps naive question from an experienced scripter.
Okay so suppose we do something like this.
function AddNewObject(obj)
local DescendantsAdded = 1 -- Gets garbage collected
print(DescendantsAdded)
end
workspace.ChildAdded:Connect(AddNewObject)
So here, DescendantsAdded stops existing and gets garbage collected because it goes out of scope.
Here something different happens however.
function AddNewObject(obj)
local DescendantsAdded = 0 -- Does not get garbage collected?
obj.DescendantAdded:Connect(function(obj2) -- Anonymous function?
DescendantsAdded += 1
print(DescendantsAdded) -- Variable keeps existing???
end
end
workspace.ChildAdded:Connect(AddNewObject)
Now DescendantsAdded seems to exist forever, at least, until we destroy the object or disconnect the function from it.
The function also is not assigned to a variable, so it’s anonymous.
Where do these exist? In what part of memory is this kept and can it still be accessed in some other way?
I feel like I should know this since I’ve been on Roblox for like 10 years but somehow I still don’t know how exactly this works.
First, values such as numbers and booleans don’t get garbage collected. They are stored in virtual registers which the compiler chooses for each variable. Only functions, tables and userdata require garbage collection.
When a function uses a local variable from a higher scope, it just grabs and works with the variable’s register (called an upvalue in the function proto).
Here’s some Lua 5.1 bytecode that should help:
local v = 1
local function f()
print(v)
end
f()
main <input-file.lua:0,0> (6 instructions, 24 bytes at 1b553702_29ec04fe)
0+ params, 3 slots, 0 upvalues, 2 locals, 1 constant, 1 function
function main(...) --line 1 through 7
1 LOADK 0 -1 ; 1
2 CLOSURE 1 0 function f() @ 0e68dea3_294c04c8
3 MOVE 0 0
4 MOVE 2 1
5 CALL 2 1 1
6 RETURN 0 1
end
function <input-file.lua:3,5> (4 instructions, 16 bytes at 0e68dea3_294c04c8)
0 params, 2 slots, 1 upvalue, 0 locals, 1 constant, 0 functions
function f() --line 3 through 5
1 GETGLOBAL 0 -1 ; print
2 GETUPVAL 1 0 ; v
3 CALL 0 2 1
4 RETURN 0 1
end
Oh thanks for this helpful insight (and pardon my late response).
Looking at this does have me wonder if anonymous functions/variables could overflow Lua’s 200 local variable limit somehow and if it would be save to use anonymous variables for storing data about an entity or character like states.