I found this part in the lua manual:
An object is considered dead as soon as the collector can be sure the
object will not be accessed again in the normal execution of the
program. ("Normal execution" here excludes finalizers, which can
resurrect dead objects (see §2.5.3), and excludes also operations using
the debug library.)
This got me wondering if in the following example the local variable
"tab" could get collected before the call to "f" since "tab" isn't
accessed any more in the normal execution due to the exlusion of the
debug library.
local function f(format)
return (string.gsub(format, "{(%w+)}", function(var)
local i, n, v = 2, debug.getlocal(4, 1)
while n ~= var do
n, v = debug.getlocal(4, i)
if n == nil then error("Var '" .. var .. "' not found") end
i = i + 1
end
return tostring(v)
end))
end
local tab = {}
collectgarbage("collect") -- tab still alive since it will be used in
the next line
print(tab)
collectgarbage("collect") -- tab collected here since it will never be
accessed in "Normal execution"
-- local tab still in scope but was collected
print(f"tab = {tab}") -- tab might be undefined
-- More sophisticated (Lua 5.1) example of string interpolation can be
found here:
--
http://lua-users.org/wiki/StringInterpolation#:~:text=Hack:%20Using%20debug%20to%20Access%20Lexicals
-- https://luarocks.org/modules/hisham/f-strings
Regards,
Xmilia
Such behavior would be compliant with the specification, and the debug library doesn't promise to always be able to tell you everything. (For example: It doesn't accurately report the full call stack when there are tail calls.) I'm not aware of it ACTUALLY invalidating locals mid-block, but that could hypothetically change.
/s/ Adam