转:https://blog.csdn.net/zxm342698145/article/details/80621238
在讲lua热更新原理第二部分之前,先介绍一下lua调试相关的函数。
调试函数能够帮助我们在开发中获取函数堆栈相关上下文信息,甚至改变函数的变量。
getinfo ([thread,] f [, what]):
返回关于一个函数信息的表。 你可以直接提供该函数, 也可以用一个数字 f 表示该函数。 数字 f 表示运行在指定线程的调用栈对应层次上的函数: 0 层表示当前函数(getinfo 自身); 1 层表示调用 getinfo 的函数 (除非是尾调用,这种情况不计入栈);等等。 如果 f 是一个比活动函数数量还大的数字, getinfo 返回 nil。
例如代码是:
local function myfun()
local a = 10
local info = debug.getinfo(1)
for k, v in pairs(info) do
print(string.format('%20s, %s', k, v))
end
end
myfun()
可以看到getinfo获取了诸如函数名,文件名,定义行等信息。
获取局部变量的函数:
debug.getlocal ([thread,] f, local):
此函数返回在栈的 f 层处函数的索引为 local 的局部变量 的名字和值。 这个函数不仅用于访问显式定义的局部变量,也包括形参、临时变量等。
local name, val
local function myfun(var)
local a = 10
local index = 1
g = 108
repeat
name, val = debug.getlocal(1, index)
print(index, name, val)
index = index + 1
until not name
end
myfun(100)
可以看出getlocal会从函数参数开始依次获取局部变量的值,直到为空。
当然我们也可以调用setlocal来改变局部变量,不过在实际的项目中好像并没有什么用,如果用setlocal改变局部变量,干嘛不直接在代码中改变局部变量呢。
setupvalue (f, up, value):
这个函数将 value 设为函数 f 的第 up 个上值。 如果函数没有那个上值,返回 nil 否则,返回该上值的名字。
关于函数的上值upvalue,简单的可以理解为函数引用的非局部变量。他这个变量也是可以获取并改变的。例如:
local function ch_up(f, name_, f_)
local i = 1
while true do
local name, value = debug.getupvalue(f, i)
if name == nil then
return false
end
if name == name_ then
debug.setupvalue(f, i, f_)
return true
end
i = i + 1
end
end
local function test()
print('raw test')
end
local wrap_test = function()
test()
end
wrap_test()
ch_up(wrap_test, 'test', function() print('new test') end)
wrap_test()
可以看到前后两次执行wrap_test()时,有不同的结果。
以上就是lua动态改变变量的理论基础,实际项目中还得灵活变通来热更新代码。