Get all variables in Lua for debug purpose with getinfo / getlocal / getupvalue

Viewed 578

I managed to get almost all variables from my Lua application with this function, but not the ones that are local to a .lua files...

Example at the root of the main.lua : local test = 10

This cannot be found.

Any idea?

Note: I'm running this in a Love2D app, and this function is called from a Love callback (love.draw).

function getvarvalue (name)
    local value, found

    -- try local variables
    local exit = false
    local level = 0
    while debug.getinfo(level) ~= nil do
        local i = 1
        while true do
            local n, v = debug.getlocal(level, i)
            if n then
                print("local "..i.." "..level.." name:"..n)
            end
            if not n then break end
            print(n)
            if n == name then
                value = v
                found = true
            end
            i = i + 1
        end
        if found then return value end
        level = level + 1
    end

    -- try upvalues
    level = 0
    while debug.getinfo(level) ~= nil do
        local func = debug.getinfo(level).func
        i = 1
        while true do
            local n, v = debug.getupvalue(func, i)
            if n~= nil then print("up "..i.." "..level.." "..n) end
            if not n then break end
            if n == name then return v end
            i = i + 1
        end
        if getfenv(func)[name] ~= nil then
            return getfenv(func)[name]
        end
        level = level + 1
    end

    -- not found
    return "?"
end
1 Answers

As @egor-skriptunoff pointed out, local variables, that are unused in a function "get killed". What does it actually mean? First, Lua treats functions as values, meaning love.draw is actually a field, where the assigned value is a function. So the function itself is created at runtime. Consider this example:

local myVar = 1

function love.draw()
    print(getvar("myVar"))
end

When Lua constructs the function, it checks which upvalues are used. And here the "kill of" happens, it doesn't detect the usage of myVar and then it doesn't create a reference to myVar. Even if it is updated in love.update. The debug API then won't show myVar, since it will only show referenced values. To force Lua to keep a reference, a simple: myVar = myVar in love.draw should do the trick.

Related