第一版是針對 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您也可以協助 支援 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 以存取呼叫函式。