2013-08-28 14 views
5

問題が発生した関数を知ることができるルアテストフレームワークをまとめようとしていますが、loadstringから_G私のテストハーネスは関数呼び出しの結果を見ることができました)私の関数は関数名に 'nil'を使い始めましたdebug.getinfo(1)に 'name'が指定されていないのはなぜですか?

_Gは次のコードで現在の関数の名前を検出できません。また、loadstringから返された結果を得るにはどうすればいいですか(すなわち、blah呼び出しから 'false')、または_Gを使用するときに関数名を設定する(つまり、関数名が何であるべきかをluaインタプリタに伝えます)。

function run_test(one, two) 
    if one ~= two then 
     print(debug.getinfo(2).name..' Failed') 
    end 
end 

function blah() 
    run_test(false, true) 
    return false 
end 

local fname = 'blah' 
local status, result = pcall(_G[fname]) -- Outputs 'nil'; result is 'false' 
local status, result = pcall(loadstring(fname..'()')) -- Outputs 'blah', result is 'nil' 

私が必要とする主なものは、テストの失敗は、失敗した関数を指すようにするために(コール内の関数名を見ることができるように、関数名の文字列を使用して関数を呼び出す方法であるようにFNAME =上記のコードで「何とか」)と、戻り値

local fname = 'blah' 
status, result = pcall(??Call fname somehow??) 
assert(status) 
assert(not result) 

--stdout should be "blah Failed" 
+0

'pcall'がC土地に入り、スタック上の関数値にこの文脈で関連するシンボリック名がないので、それは可能でしょうか? – greatwolf

+0

どちらの行もpcallを使用しています。さらに、ロードストリングが_Gより動的な "より動的"なので、逆のことです。 –

+0

はい、2行目は 'blah'よりも無名関数をラップする効果があり、これがルアランドに戻ります。 – greatwolf

答えて

4

これは関数の名前を提供するためのLUAが使用するヒューリスティックの制限であるを得ることができます。

ルアでは、すべての機能が匿名です。与えられた関数は、いくつかの変数(グローバル、ローカル、テーブルの各フィールド)の値になります。 Luaデバッグシステムは、実行されているバイトコードを調べることによって、どこから来たのかに基づいて値の合理的な名前を見つけようとします。

は単純例に最初の呼び出しで

blah() 
pcall(blah) 

を考えてみましょう、デバッグシステムは、呼び出される関数がグローバルblahから来ていることを見て、debug.getinfo(1).name期待される結果、blahを与えます。

2番目の呼び出しでは、デバッグシステムは、呼び出される関数がpcallに最初の引数から来ていることを見ているが、それはその引数がどこから来たのを見て、さらに見ていない、とdebug.getinfo(1).namenilを与えます。

_G[name]()と同じことが起こります。すべてのデバッグシステムにはテーブルのフィールドがあり、フィールドの名前が離れすぎています。

この説明をもう一度参照するには、blahの最初の行にprint(debug.traceback())を追加してみてください。

+0

私の2番目の質問のアイデア? –

+0

@solarmistあなたは返品結果を返すという質問に言及していますか? 'blah'が返すものを取り戻すことを意味しますか? – greatwolf

+0

はい、「blah」が返すものを返すか、_G呼び出しの名前を偽って返します。 –

関連する問題