lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, 2010-11-24 at 21:56 -0200, Luiz Henrique de Figueiredo wrote:
> > So, how can I inspect and change the local variables in the scope that
> > debug.debug() was called? Does it mean that I have to use functions like
> > debug.getinfo() and debug.getlocal() to access the current context?
> 
> Yes.
>  
> > There surely must be a simpler way... :)
> 
> Use a real debugger; debug.debug is very simple minded.
> 

Ok, I managed to solve it by creating a custom version of the function
that also enables read/write access to locals by fiddling with the
environment. You can now access the locals like if they were global
variables. For those interested, the code is below.

Note that it doesn't handle correctly the case when there are locals of
the same name in one scope, but works across different scopes -
correction left as an exercise to the reader ;)

function DEBUG()
    local G = _G
    local locals = {}
    local max = 1000000
    for l=2, max do
        local info = debug.getinfo(l, "f")
        if not info then break end
        for i=1, max do
            local name, val = debug.getlocal(l, i)
            if not name then break end
            locals[name] = locals[name] or { where = l + 2, index = i,
val = val, set = debug.setlocal }
        end
        local f = info.func
        for i=1, max do
            local name, val = debug.getupvalue(f, i)
            if not name then break end
            locals[name] = locals[name] or { where = f, index = i, val =
val, set = debug.setupvalue }
        end
    end
    local ENV = setmetatable({}, {
        __index = function(t,k)
            if locals[k] then return locals[k].val
            else return G[k]
            end
        end,
        __newindex = function(t,k,v)
            if locals[k] then
                local t = locals[k]
                t.val = v
                t.set(t.where, t.index, v)
            else G[k] = v
            end
        end
    })
    local input
    while true do
        io.write('DEBUG> ')
        input = io.read()
        if input == 'cont' then break end
        local f, err = loadstring(input, "debug")
        if not f then print('Error:', err)
        else
            local ok, err = pcall(setfenv(f, ENV))
            if not ok then print('Error:', err) end
        end
    end
end