Скажем, у вас есть этот код:
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)
Величина й не связана с й в любом случае, формой, или формы. Если вы хотите вручную назвать функцию, вы можете это сделать, обернув функцию в таблице, например:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, {
name = "MyFunctionName",
func = x
})
То есть, как вы могли бы сделать это!
... если ..
..you нарушать правила!
Когда Lua была разработана, разработчики поняли, что анонимный характер функций затруднит создание продуктивных сообщений об ошибках, если не невозможно.
Самое лучшее, что вы бы увидели бы:
stdin: some error!
stdin: in function 'unknown'
stdin: in function 'unknown'
Таким образом, они сделали так, что когда Lua код был разобран, он будет записывать некоторые отлаживать информацию, чтобы сделать жизнь проще. Для доступа к этой информации от самого Lua предоставляется debug library.
Будьте очень осторожны с функциями в этой библиотеке.
Вы должны проявлять осторожность при использовании этой библиотеки. Предоставленные здесь функции должны использоваться исключительно для отладки и подобных задач, таких как профилирование. Не поддавайтесь искушению использовать их в качестве обычного инструмента программирования: они могут быть очень медленными. Более того, некоторые из этих функций нарушают некоторые предположения относительно кода 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
) и выше версию требует, чтобы запустить функцию.
Кажется безнадежным!
... если ..
..you действительно нарушать правила.
Функция debug.sethook
позволяет прерывать запуск кода Lua на определенных событиях и даже изменять вещи, пока все это происходит. Это, в сочетании с coroutines, позволяет вам делать некоторые интересные хакеры.
Вот реализация 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))
Эта функция не очень надежна - она работает иногда, а не другие. Библиотека отладки очень обидна, поэтому ее можно ожидать.
Обратите внимание, что вы должны никогда использовать это для фактического кода выпуска! Только для отладки!
Самый крайний случай, который по-прежнему приемлем, - это ошибки регистрации на выпущенном программном обеспечении, чтобы помочь разработчику исправить проблемы. Ни один жизненный код не должен зависеть от функций из библиотеки отладки.
Удачи вам!
С выпуском 5.2 они немного смягчают ограничение.Уведомление в руководстве перешло от «Пожалуйста, сопротивляйтесь искушению использовать их в качестве обычного инструмента программирования» на «Вы должны проявлять осторожность при использовании этой библиотеки». Поэтому будьте осторожны и знаете, что вы делаете, но вы можете использовать это :). – jpjacobs
Комплексный ответ :) Просто сделаем небольшую заметку о том, что имя функции в соответствии с библиотекой отладки не берется из разбора, а из имени, используемого для вызова функции во время выполнения. – MattJ
Хорошо, что объясняет, почему 'debug.getfuncname' почти никогда не работает ... – Deco