Распечатайте все локальные переменные, доступные для текущей области в Lua

Я знаю, как распечатать "все" глобальные переменные с помощью следующего кода

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

Таким образом, мой вопрос состоит в том, как сделать это для всех переменных, которые доступны от в настоящее время выполняющейся функции, что-то, что может сделать что locals() делает для Python.

27
задан Edu Felipe 14 May 2010 в 13:46
поделиться

4 ответа

Вот реализация функции 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
34
ответ дан 28 November 2019 в 05:19
поделиться

Вы можете использовать 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 , либо с помощью метатаблиц.

0
ответ дан 28 November 2019 в 05:19
поделиться

Use debug.getlocal.

6
ответ дан 28 November 2019 в 05:19
поделиться

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
2
ответ дан 28 November 2019 в 05:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: