2016-05-18 7 views
2

私はLuaスクリプトですべての関数を取得する方法を理解しようとしています。このスクリプトは、loadfileを通して関数にコンパイルされています。たとえば、以下のスクリプトで定義されているすべての関数を取得したいと考えています。Luaスクリプトですべての関数を取得する

function example1() 

end 

local function example2() 

end 

local library = {} 

function library:example3() 

end 

(function() 
    -- Functions like this too. 
end) 

名前は重要ではありません、私はちょうど私がdebug.getinfoでそれらを使用し、それらが定義されていたラインのような情報を得ることができるので、実際の機能を取得する方法を探しています。私はLuaJITを持っていますそれがあればこれは簡単になります。このようなことは可能ですか?前もって感謝します。

答えて

1

各関数定義が代入(例では異なる形式)であるため、シンタックスやバイトコード解析がなければ、これは可能ではありません。 bytecode inspectorおよび関連する説明hereを参照してください。構文解析では、metaluaなど、lua-loose-parserなどを使用できます。 loadstring(またはそれに類似したメソッド)を使用して動的に定義される関数もありますので、これらのツールでも関数のリスト全体が表示されるわけではありません。

loadfileの結果にしかアクセスできない場合は、バイトコードアナライザを使用するのが最善の方法です。

2

ファイルは、その関数がグローバルであると宣言しているか、返されたものを本当に追跡するのは簡単でしょう。その場合は

、あなたはそれらのすべてのループのための一般的なグローバル項目、およびだけ取る機能を一巡することができます

allFuncs = {} 

for key, item in pairs(_G) do 
    if type(item) == "function" then 
     allFuncs[#allFuncs + 1] = item 
    end 
end 

_Gは、すべてのグローバル変数を保持するテーブルです)

すべての関数を宣言したリスト(allFuncs)がありますが、setmetatablexpcallなどの既定の関数も含まれていることに注意してください。

これが実現するしないようにコードを変更するのは簡単ですが、唯一のテスト/学習のためにこれを使用します。

function allFuncs() 
    local funcsTab = {} 
    for key, item in pairs(_G) do 
     if type(item) == "function" then 
      funcsTab[#funcsTab + 1] = item 
     end 
    end 
    return funcsTab 
end 

defaultFuncs = allFuncs() 

--then you load your file: other functions get declared 
--we create another table containg the default + the new functions 

myFuncs = allFuncs() 

--then you subtract the first table from the second 

for i = 1, #myFuncs do 
    for o = 1, #defaultFuncs do 
     if myFuncs[i] == defaultFuncs[o] then 
      table.remove(myFuncs, i) 
     end 
    end 
end 

ファイルが何かを返し、グローバルとしての機能を宣言していない場合、これはあります。

ファイルがそれらをローカルとして宣言し、それを含むテーブルを返した場合は、_Gをその返されたテーブルに置き換える最初のコードを使用してください。

+0

スクリプトはダイナミックになるでしょう(ユーザーが作成した別の場所から来ています)。スクリプトに定義されているすべての関数を取得する必要があります。グローバル関数ではありません。ありがとう、結構です! –

+0

しかし、そのスクリプトはどのように関数を宣言しますか?それを「ローカル」と宣言してから、テーブルに戻しますか?それとも、何も返さずにグローバル関数として宣言するだけですか?テーブルを返す場合は、上記のコードを '_G'をその返されたテーブルに置き換えることができます。 – user6245072

関連する問題