web-dev-qa-db-ja.com

Luaの現在のスコープにアクセス可能なすべてのローカル変数を出力します

次のコードを使用して「すべての」グローバル変数を出力する方法を知っています

_for k,v in pairs(_G) do
    print("Global key", k, "value", v)
end
_

だから私の質問は、現在実行中の関数からアクセスできるすべての変数に対してそれを行う方法です。これは、Pythonに対してlocals()が行うことを実行できるものです。

27
Edu Felipe

これは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
_
34
u0b34a0f6ae

使用する debug.getlocal

6
lhf

見る - 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
2
Judge Maygarden

上記のメイガーデン裁判官のループバージョンの問題は、単にlocal i = 0です。 '0'でインデックス付けされた最初のものは常にnilを返すため、何もしません。

Luaインデックスは、C/C++のように「0」ではなく、デフォルトで「1」で始まることに注意してください。もちろん、独自のタイプのインデックスには「0」を使用できますが、デフォルトの関数では、最初のインデックスとしてデフォルトの「1」が必要です。

local i = 1に変更するだけで、彼のループは正常に機能します。

2
Sirmabus

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を定義できます。

0