скажем, у вас есть этот код:
t = {}
x = 5
table.insert(t, 1, x)
t
тогда будет {[1] = 5}
. «5» - это просто число - оно не имеет имени и не связано с переменной «x»; это значение .
В Lua функции обрабатываются точно так же, как значения :
t = {}
x = function() print("test! :D") end
table.insert(t, 1, x)
Значение x никак не связано с x, ни формой, ни формой. Если вы хотите вручную назвать функцию, вы можете сделать это, поместив функцию в таблицу, например:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, {
name = "MyFunctionName",
func = x
})
Вот как бы вы это сделали!
... если ..
.. вы нарушаете правила!
Когда был разработан Lua, разработчики поняли, что анонимный характер функций затруднит создание продуктивных сообщений об ошибках, если не будет невозможным.
Лучшее, что вы увидите, будет:
stdin: some error!
stdin: in function 'unknown'
stdin: in function 'unknown'
Итак, они сделали так, чтобы при разборе кода Lua он записывал некоторую отладочную информацию, чтобы облегчить жизнь. Для доступа к этой информации из самого Lua предоставляется библиотека отладки .
Будьте очень осторожны с функциями в этой библиотеке.
Вы должны проявлять осторожность при использовании этой библиотеки. Функции, представленные здесь, должны использоваться исключительно для отладки и подобных задач, таких как профилирование. Пожалуйста, не поддавайтесь искушению использовать их как обычный инструмент программирования: они могут быть очень медленными. Более того, некоторые из этих функций нарушают некоторые предположения о коде Lua (например, что локальные для функции переменные не могут быть доступны извне или что метатаблицы пользовательских данных не могут быть изменены кодом Lua) и, следовательно, могут поставить под угрозу безопасность кода в противном случае. .
Для достижения желаемого эффекта вы должны использовать функцию debug.getinfo
; пример:
x = function()
print("test!")
print(debug.getinfo(1, "n").name)
end
x() -- prints "test!" followed by "x"
К сожалению, форма debug.getinfo, которая работает непосредственно с функцией, не заполняет аргумент name
(debug.getinfo(x, "n").name == nil
), и в приведенной выше версии вам необходимо запустить функцию.
Кажется безнадежным!
... если ..
.. Вы действительно нарушаете правила.
Функция debug.sethook
позволяет вам прерывать выполнение кода Lua при определенных событиях и даже изменять вещи, пока все это происходит. Это, в сочетании с сопрограммами , позволяет делать интересные вещи.
Вот реализация debug.getfuncname
:
function debug.getfuncname(f)
--[[If name found, returns
name source line
If name not found, returns
nil source line
If error, returns
nil nil error
]]
if type(f) == "function" then
local info = debug.getinfo(f, "S")
if not info or not info.what then
return nil, nil, "Invalid function"
elseif info.what == "C" then
-- cannot be called on C functions, as they would execute!
return nil, nil, "C function"
end
--[[Deep magic, look away!]]
local co = coroutine.create(f)
local name, source, linedefined
debug.sethook(co, function(event, line)
local info = debug.getinfo(2, "Sn")
name = info.namewhat ~= "" and info.name or nil
source, linedefined = info.short_src, info.linedefined
coroutine.yield() -- prevent function from executing code
end, "c")
coroutine.resume(co)
return name, source, linedefined
end
return nil, nil, "Not a function"
end
Пример использования:
function test()
print("If this prints, stuff went really wrong!")
end
print("Name = ", debug.getfuncname(test))
Эта функция не очень надежна - иногда она работает, а другие нет. Библиотека отладки очень обидчива, так что этого следовало ожидать.
Обратите внимание, что вы никогда не должны использовать это для фактического кода выпуска! Только для отладки!
Самый крайний случай, который все еще приемлем, - это регистрация ошибок на части выпущенного программного обеспечения, чтобы помочь разработчику решить проблемы. Никакой жизненно важный код не должен зависеть от функций из библиотеки отладки.
Удачи!