第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助 支持 Lua 项目


23.1.2 – 访问上值

debug 库还允许我们使用 getupvalue 访问 Lua 函数使用的上值。但是,与局部变量不同,函数在不活动时也有其上值(毕竟,这就是闭包的意义所在)。因此,getupvalue 的第一个参数不是堆栈级别,而是函数(更确切地说,是闭包)。第二个参数是上值索引。Lua 按函数中首次引用的顺序对上值进行编号,但此顺序无关紧要,因为函数不能有两个具有相同名称的上值。

您还可以使用 debug.setupvalue 更新上值。正如您可能期望的那样,它有三个参数:一个闭包、一个上值索引和一个新值。与 setlocal 一样,它返回上值的名称,如果上值索引超出范围,则返回 nil

以下代码显示了如何给定变量名称访问调用函数的任何给定变量的值

    function getvarvalue (name)
      local value, found
    
      -- try local variables
      local i = 1
      while true do
        local n, v = debug.getlocal(2, i)
        if not n then break end
        if n == name then
          value = v
          found = true
        end
        i = i + 1
      end
      if found then return value end
    
      -- try upvalues
      local func = debug.getinfo(2).func
      i = 1
      while true do
        local n, v = debug.getupvalue(func, i)
        if not n then break end
        if n == name then return v end
        i = i + 1
      end
    
      -- not found; get global
      return getfenv(func)[name]
    end
首先,我们尝试一个局部变量。如果有多个变量具有给定的名称,我们必须获取具有最高索引的变量;因此,我们必须始终遍历整个循环。如果我们找不到具有该名称的任何局部变量,则尝试上值。首先,我们使用 debug.getinfo(2).func 获取调用函数,然后遍历其上值。最后,如果我们找不到具有该名称的上值,则获取全局变量。请注意在调用 debug.getlocaldebug.getinfo 时使用参数 2 来访问调用函数。