次のコードを使用して「すべての」グローバル変数を出力する方法を知っています
_for k,v in pairs(_G) do
print("Global key", k, "value", v)
end
_
だから私の質問は、現在実行中の関数からアクセスできるすべての変数に対してそれを行う方法です。これは、Pythonに対してlocals()
が行うことを実行できるものです。
これはlocals()
関数の実装です。呼び出しスコープからローカルのテーブルを返します。
_function locals()
local variables = {}
local idx = 1
while true do
local ln, lv = debug.getlocal(2, idx)
if ln ~= nil then
variables[ln] = lv
else
break
end
idx = 1 + idx
end
return variables
end
_
Lua REPLでは、各行が個別のローカルを持つ個別のチャンクであることに注意してください。また、内部変数が返されます(名前は、削除する場合は '('で始まります):
_> local a = 2; for x, v in pairs(locals()) do print(x, v) end
a 2
(*temporary) function: 0x10359b38
_
受け入れてくれてありがとう。パズルの最後のピースのロックを解除しました! ;-)
アップバリューは、現在の関数で使用される外部スコープからのローカル変数です。それらは__G
_にもlocals()
にもありません
_function upvalues()
local variables = {}
local idx = 1
local func = debug.getinfo(2, "f").func
while true do
local ln, lv = debug.getupvalue(func, idx)
if ln ~= nil then
variables[ln] = lv
else
break
end
idx = 1 + idx
end
return variables
end
_
例(表示するには、を使用する必要があることに注意してください):
_> local a= 2; function f() local b = a; for x,v in pairs(upvalues()) do print(x,v) end end; f()
a 2
_
使用する debug.getlocal
。
見る - debug.getlocal
:
local foobar = 1
local i = 0
repeat
local k, v = debug.getlocal(1, i)
if k then
print(k, v)
i = i + 1
end
until nil == k
出力:
foobar 1
i 2
上記のメイガーデン裁判官のループバージョンの問題は、単にlocal i = 0
です。 '0'でインデックス付けされた最初のものは常にnilを返すため、何もしません。
Luaインデックスは、C/C++のように「0」ではなく、デフォルトで「1」で始まることに注意してください。もちろん、独自のタイプのインデックスには「0」を使用できますが、デフォルトの関数では、最初のインデックスとしてデフォルトの「1」が必要です。
local i = 1
に変更するだけで、彼のループは正常に機能します。
getfenv を使用してローカル環境を取得できます。
getfenv([f])関数が使用している現在の環境を返します。 fは、Lua関数、またはそのスタックレベルで関数を指定する数値にすることができます。レベル1は、getfenvを呼び出す関数です。指定された関数がLua関数でない場合、またはfが0の場合、getfenvはグローバル環境を返します。 fのデフォルトは1です。
編集:すみません、私は間違っていました。
Luaのソースコードを確認しました。 debug.getlocal()
は、ローカル変数を取得する唯一の方法です。
Luaは内部 Proto 構造を使用しており、それにアクセスすることはできません。
(Protoは、ローカルプロパティと親Proto参照を保持します。getfenvを使用して関数のProtoを反復します。
また、必要なものではなく、継承されたプロパティを繰り返します)
ユーザーは、環境とset/getfenv
関数を使用するか、メタテーブルを使用して、Protoを定義できます。