Распечатайте все локальные переменные, доступные для текущей области в Lua
Я знаю, как печатать "все" глобальные переменные, используя следующий код
for k,v in pairs(_G) do
print("Global key", k, "value", v)
end
Итак, мой вопрос заключается в том, как сделать это для всех переменных, доступных из текущей исполняемой функции, что может сделать то, что locals()
для Python.
Ответы
Ответ 1
Вот реализация функции 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
Спасибо за согласие. Вы разблокировали последний кусочек головоломки!; -)
Upvalues - это локальные переменные из внешних областей, которые используются в текущей функции. Они не находятся ни в _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
Ответ 2
Используйте debug.getlocal
.
Ответ 3
См. 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
Ответ 4
Проблема с версией цикла Judge Maygarden выше просто local i = 0
.
Он ничего не делает, потому что первый индекс с "0" всегда будет возвращать нуль.
Помните, что индексы Lua по умолчанию начинаются с "1", а не "0" , как C/С++.
Вы можете использовать "0" для индекса с вашими типами курсов, но функции по умолчанию
ожидают, что по умолчанию "1" будет первым индексом.
Просто измените его на local i = 1
, и его цикл будет работать нормально.
Ответ 5
Вы можете использовать getfenv, чтобы получить локальную среду.
getfenv ([f]) Возвращает текущий окружающая среда, используемая функцией. е может быть функцией Lua или числом, которое определяет функцию в этом стеке level: Уровень 1 - вызов функции getfenv. Если данная функция не является функция Lua, или если f равно 0, getfenv возвращает глобальную среду. значение по умолчанию для f равно 1.
Изменить: извините, я ошибся.
Я только что проверил исходный код Lua. debug.getlocal()
- единственный способ получить локальные переменные.
Lua использует внутреннюю структуру Proto и не дает нам доступ к этому.
(Proto содержит локальные свойства, а также родительскую ссылку Proto. Итерационная функция Proto, используя getfenv,
мы также итерируем унаследованные свойства, а не то, что хотели)
Пользователи могут определять свои Proto с средами и функциями set/getfenv
или с помощью метатегов.