天天看點

lua程式設計(第四版)練習答案自做(第二十五章)

文章目錄

      • 25.1
      • 25.2
      • 25.3
      • 25.4
      • 25.5
      • 25.6
      • 25.7
      • 25.8

25.1

#!/usr/bin/lua
function getvarvalue(...)
        local co=...
        if type(co)=="thread" then
                local name,level,isenv=select(2,...)
                local value
                local found=false
                level=level or 1
                for i=1,math.huge do
                        local n,v=debug.getlocal(co,level,i)
                        if not n then
                                break
                        end
                        if n==name then
                                value=v
                                found=true
                        end
                end
                if found then
                        return "local",value
                end
                local func=debug.getinfo(co,level,"f").func
                for i=1,math.huge do
                        local n,v=debug.getupvalue(func,i)
                        if not n then
                                break
                        end
                        if n==name then
                                return "upvalue",v
                        end
                end
                if isenv then
                        return "noenv"
                end
                local _,env=getvarvalue(co,"_ENV",level,true)
                if env then
                        return "global",env[name]
                else
                        return "noenv"
                end
        else
                local name,level,isenv=...
                local value
                local found=false
                level=(level or 1)+1
                for i=1,math.huge do
                        local n,v=debug.getlocal(level,i)
                        if not n then
                                break
                        end
                        if n==name then
                                value=v
                                found=true
                        end
                end
                if found then
                        return "local",value
                end
                local func=debug.getinfo(level,"f").func
                for i=1,math.huge do
                        local n,v=debug.getupvalue(func,i)
                        if not n then
                                break
                        end
                        if n==name then
                                return "upvalue",v
                        end
                end
                if isenv then
                        return "noenv"
                end
                local _,env=getvarvalue("_ENV",level,true)
                if env then
                        return "global",env[name]
                else
                        return "noenv"
                end
        end
end
           

25.2

#!/usr/bin/lua
function setvarvalue(name,value,level)
        level=(level or 1)+1
        for i=1,math.huge do
                local n,v=debug.getlocal(level,i)
                if not n then
                        break
                end
                if n==name then
                        debug.setlocal(level,i,value)
                        return "local"
                end
        end

        local func=debug.getinfo(level,"f").func
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n==name then
                        debug.setupvalue(func,i,value)
                        return "upvalue"
                end
        end
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n=="_ENV" then
                        v[name]=value
                        return "global"
                end
        end
end
           

25.3

#!/usr/bin/lua
function getvarvalue()
        local res={}
        local level=2
        local env
        for i=1,math.huge do
                local n,v=debug.getlocal(level,i)
                if not n then
                        break
                end
                res[n]=v
        end
        local func=debug.getinfo(level,"f").func
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n=="_ENV" then
                        env=v
                end
                res[n]=v
        end
        if env then
                res.__index=env
                setmetatable(res,res)
        end
        return res
end
           

25.4

#!/usr/bin/lua
function getvarvalue(_,name,level,isenv)
        local value
        local found=false
        level=(level or 3)+1
        for i=1,math.huge do
                local n,v=debug.getlocal(level,i)
                if not n then
                        break
                end
                if n==name then
                        value=v
                        found=true
                end
        end
        if found then
                return value
        end
        local func=debug.getinfo(level,"f").func
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n==name then
                        return v
                end
        end
        if isenv then
                return "noenv"
        end
        local env=getvarvalue(nil,"_ENV",level,true)
        if env then
                return env[name]
        else
                return "noenv"
        end
end
function setvarvalue(_,name,value,level)
        level=(level or 3)+1
        for i=1,math.huge do
                local n,v=debug.getlocal(level,i)
                if not n then
                        break
                end
                if n==name then
                        debug.setlocal(level,i,value)
                        return "local"
                end
        end
        local func=debug.getinfo(level,"f").func
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n==name then
                        debug.setupvalue(func,i,value)
                        return "upvalue"
                end
        end
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n=="_ENV" then
                        v[name]=value
                        return "global"
                end
        end
end
function debug1()
        while true do
                io.write("debug> ")
                local line=io.read()
                if line=="cont" then
                        break
                end
                local env={print=print,__index=getvarvalue,__newindex=setvarvalue}
                setmetatable(env,env)
                load(line,"testcode","t",env)()
        end
end
           

25.5

#!/usr/bin/lua
function getvarvalue(_,name,level,isenv)
        local value
        local found=false
        level=(level or 3)+1
        for i=1,math.huge do
                local n,v=debug.getlocal(level,i)
                if not n then
                        break
                end
                if n==name then
                        value=v
                        found=true
                end
        end
        if found then
                return value
        end
        local func=debug.getinfo(level,"f").func
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n==name then
                        return v
                end
        end
        if isenv then
                return "noenv"
        end
        local env=getvarvalue(nil,"_ENV",level,true)
        if env then
                return env[name]
        else
                return "noenv"
        end
end
function setvarvalue(_,name,value,level)
        level=(level or 3)+1
        for i=1,math.huge do
                local n,v=debug.getlocal(level,i)
                if not n then
                        break
                end
                if n==name then
                        debug.setlocal(level,i,value)
                        return "local"
                end
        end
        local func=debug.getinfo(level,"f").func
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n==name then
                        debug.setupvalue(func,i,value)
                        return "upvalue"
                end
        end
        for i=1,math.huge do
                local n,v=debug.getupvalue(func,i)
                if not n then
                        break
                end
                if n=="_ENV" then
                        v[name]=value
                        return "global"
                end
        end
end
function debug1()
        while true do
                io.write("debug> ")
                local line=io.read()
                if line=="cont" then
                        break
                end
                local env={print=print,__index=getvarvalue,__newindex=setvarvalue}
                setmetatable(env,env)
                load(line,"testcode","t",env)()
        end
end
           

25.6

待完善

25.7

local breakpoint={}
local function hook(event,line)
        if breakpoint[line] then
                debug.debug()
        end
end
local function setbreakpoint(func,line)
        breakpoint[line]=true
        if not debug.gethook() then
                debug.sethook(hook,"l")
        end
        return line
end
local function removebreakpoint(handle)
        breakpoint[handle]=nil
end
return {
        setbreakpoint=setbreakpoint,
        removebreakpoint=removebreakpoint,
}
           

25.8

待完善