この初版はLua 5.0向けに書かれました。後続バージョンでも大部分は関連性がありますが、いくつかの違いがあります。
第4版はLua 5.3を対象としており、Amazonおよびその他の書店で購入できます。
本書を購入することで、Luaプロジェクトの支援にもなります。


23.1 – 自己検査機能

デバッグライブラリにおける主要な自己検査関数は、debug.getinfo関数です。その最初の引数は、関数またはスタックレベルです。ある関数fooに対してdebug.getinfo(foo)を呼び出すと、その関数に関するデータを含むテーブルを取得します。そのテーブルには、以下のフィールドが含まれる場合があります。

fooがC関数の場合、Luaはその関数に関するデータはあまり持ちません。このような関数では、whatnamenamewhatフィールドのみが関連します。

ある数値nに対してdebug.getinfo(n)を呼び出すと、そのスタックレベルでアクティブな関数に関するデータを取得します。例えば、nが1の場合、呼び出しを行っている関数に関するデータを取得します。(nが0の場合、getinfo自体(C関数)に関するデータを取得します。)nがスタック内のアクティブな関数の数よりも大きい場合、debug.getinfonilを返します。アクティブな関数を照会する場合、数値でdebug.getinfoを呼び出すと、結果のテーブルには、関数がその時点で存在する行を示すcurrentlineという追加フィールドが含まれます。さらに、funcにはそのレベルでアクティブな関数が含まれます。

nameフィールドは扱いが難しいです。Luaでは関数が第一級の値であるため、関数は名前を持たない場合や、複数の名前を持つ場合があります。Luaは、その値を持つグローバル変数を探すこと、または関数を呼び出したコードを調べて呼び出し方法を確認することによって、関数の名前を見つけようとします。この2番目のオプションは、数値を使用してgetinfoを呼び出す場合、つまり特定の呼び出しに関する情報を取得する場合にのみ機能します。

getinfo関数は効率的ではありません。Luaは、プログラムの実行を妨げない形式でデバッグ情報を保持しています。効率的な取得はここでは二次的な目標です。パフォーマンスを向上させるために、getinfoには、取得する情報を選択するオプションの第2引数があります。この引数を使用すると、ユーザーが必要としていないデータの収集に時間を無駄にすることはありません。この引数の形式は文字列であり、各文字は次の表に従ってデータのグループを選択します。

`n´nameフィールドとnamewhatフィールドを選択します。
`f´funcフィールドを選択します。
`S´sourceshort_srcwhatlinedefinedフィールドを選択します。
`l´currentlineフィールドを選択します。
`u´nupフィールドを選択します。

次の関数は、debug.getinfoの使用方法を示しています。アクティブなスタックのプリミティブなトレースバックを出力します。

    function traceback ()
      local level = 1
      while true do
        local info = debug.getinfo(level, "Sl")
        if not info then break end
        if info.what == "C" then   -- is a C function?
          print(level, "C function")
        else   -- a Lua function
          print(string.format("[%s]:%d",
                              info.short_src, info.currentline))
        end
        level = level + 1
      end
    end
getinfoからより多くのデータを含めるなど、この関数を改善するのは難しくありません。実際、デバッグライブラリには、そのような改良版であるdebug.tracebackが用意されています。当社のバージョンとは異なり、debug.tracebackは結果を出力しません。代わりに、文字列を返します。