Lua: проверьте локальную или глобальную переменную - PullRequest
0 голосов
/ 10 ноября 2018

Есть ли способ проверить, является ли переменная глобальной или локальной? Я имею в виду сделать это с помощью средств программирования, а не путем чтения кода? Например

print(type(a))=>"number", 
print(checklocal(a))=>true

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Местонахождение любой заданной переменной всегда можно определить из источника, поэтому, если вы программируете на чистом Lua, я не вижу никакой цели этого. Я полагаю, что это может быть полезно в тех случаях, когда вы, возможно, выполняете некоторую предварительную обработку, поэтому вот один из способов сделать это без необходимости зависеть от имени:

local variable
print(debug.getupvalue(function()variable()end, 1) ~= "_ENV")

function()variable()end, для локальной переменной, захватит ее как повышающее значение (debug.getupvalue вернет "variable"). Если вместо variable разрешается глобальная переменная, функция должна хранить вместо этого глобальное окружение _ENV в качестве повышающего значения (которое индексируется с именем переменной). Нет необходимости вызывать variable в функции, это просто кратчайший способ ее «использовать». Если variable равно _ENV, оно всегда печатает false (даже если _ENV всегда локально).

Еще одна опция, которая работает правильно для _ENV:

local variable
print(debug.getupvalue(function()_ENV(variable)end, 2) ~= nil)

function()_ENV(variable)end всегда захватывает _ENV, а также variable, если он локальный, поэтому проверка второго индекса определяет, была ли переменная локальной или нет.

Это работает с Lua 5.2 и далее.

Для решения без использования библиотеки отладки вы можете временно установить метаметод __newindex на _ENV, присвоить некоторые значения и проверить, вызывается ли метаметод.

0 голосов
/ 10 ноября 2018

Переменные являются локальными в определенной области. Да, вы можете получить доступ к локальным переменным любой активной функции, вызвав debug.getlocal(StackLevel, Index), она возвращает два значения:

  1. Имя переменной
  2. Значение переменной

     -- Example 
     local isGlobal = 99
     function testFunc(var)
         local v1, v2, v3 = 1, 2, 3
         local a = 1
         while true do
             local name, value = debug.getlocal(1, a)
             if not name then break end
             print(name, value)
             a = a + 1
         end
    end
    
    testFunc('xyz')
    -- Result
    --   var    xyz
    --   v1     1
    --   v2     2
    --   v3     3
    --   a      5
    

local isGlobal = 99 выходит за рамки нашего testFunc(), поэтому getlocal не будет его печатать, тогда как все остальные переменные в пределах нашего testFunc будут напечатаны со своими значениями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...