初版は Lua 5.0 用に書かれました。後期のバージョンでも依然として関連性は高いものの、相違点もいくつかあります。
第 4 版では Lua 5.3 をターゲットにしており、Amazon やその他の書店で購入できます。
書籍を購入すると、Lua プロジェクトをサポートすることにもつながります。


23.1.2 – アップバリューへのアクセス

debug ライブラリでは、getupvalue を使用して Lua 関数が使用するアップバリューにもアクセスできます。ただし、ローカル変数とは異なり、関数にはアクティブでない場合でもアップバリューがあります (それがクロージャの役割です)。そのため、getupvalue の第 1 引数はスタックレベルではなく、関数 (つまり、より正確にはクロージャ) です。第 2 引数はアップバリューのインデックスです。アップバリューは、関数内で最初に参照された順に Lua 内で番号が付けられますが、関数が同じ名前のアップバリューを 2 つ持つことはできないため、この順序は関係ありません。

debug.setupvalue を使用してアップバリューを更新することもできます。予想される通り、これには 3 つのパラメータがあります: クロージャ、アップバリューインデックス、および新しい値です。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 を使用して、呼び出し関数にアクセスすることに注意してください。