Я знаю, как распечатать "все" глобальные переменные с помощью следующего кода
for k,v in pairs(_G) do
print("Global key", k, "value", v)
end
Таким образом, мой вопрос состоит в том, как сделать это для всех переменных, которые доступны от в настоящее время выполняющейся функции, что-то, что может сделать что locals()
делает для Python.
Вот реализация функции 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
Пример (обратите внимание, что для его отображения необходимо использовать a):
> local a= 2; function f() local b = a; for x,v in pairs(upvalues()) do print(x,v) end end; f()
a 2
Вы можете использовать getfenv , чтобы получить локальную среду.
getfenv ([f]) Возвращает текущую среду , используемую функцией. f может быть функцией Lua или числом, которое определяет функцию на этом уровне стека : Уровень 1 - это функция, вызывающая getfenv. Если данная функция не является функцией Lua или если f равно 0, getfenv возвращает глобальное окружение. По умолчанию для f равно 1.
Изменить: извините, я ошибался.
Я только что проверил исходный код Lua. debug.getlocal ()
- единственный способ получить локальные переменные.
Lua использует внутреннюю структуру Proto и не дает нам доступа к ней.
(Proto содержит локальные свойства плюс родительскую ссылку Proto. Итерируя Proto функции, используя getfenv,
мы также повторяем унаследованные свойства, а не то, что мы хотели)
Пользователи могут определять свои Proto либо с помощью окружений и функций set / getfenv
, либо с помощью метатаблиц.
See 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
Output:
foobar 1
i 2