В вопросе отсутствует очень важная деталь: почему?
Если вы хотите это для отладки, тогда debug.sethook
, вероятно, является более подходящим вариантом. Как отметил Пол Кульченко, debug.getinfo
может возвращать неправильное имя функции, но он также возвращает сам объект функции, который можно использовать для поиска канонического имени в таблице. Это может также служить фильтром для функций, которые нужно отслеживать:
local watch = {}
debug.sethook(function()
local info = debug.getinfo(2)
if watch[info.func] then
print(watch[info.func], "was called")
-- This *should* not cause a recursion, as
-- the hook *should* be disabled inside the hook
-- callback.
end
end, "c")
-- Somewhere else in your code
watch[print] = "print"
print("foobar")
Однако, если вы собираетесь использовать это для чего-либо кроме отладки, вам следует избегать debug.sethook
, когда это возможно, так как это может связываться с другими библиотеками, которые используют отладочные хуки (например, luacov
, чтобы назвать пример); в этом случае было бы лучше заменить функцию:
do local p = print
function print(...)
p("Print was called!")
return p(...)
end
end
, но имейте в виду, что вам не следует изменять поведение ahy-функций, иначе вы можете нарушить код где-то еще. Это также включает время выполнения; если вы выполняете очень производительную функцию, выполняющую много тяжелой работы, это может привести к непредсказуемому снижению производительности.
Также имейте в виду, что некоторые библиотеки локализуют глобальные функции, которые они ожидают использовать. Хотя это, как правило, очень плохая практика, существует миф о том, что это волшебным образом ускоряет Lua код (есть причина для этого мифа, но в большинстве случаев это не так); это означает, что ваша замена должна произойти до того, как загрузится любая из этих библиотек.
По этой же причине, кстати, вам обычно не следует локализовать глобальные переменные, если вы не уверены, что вам нужен постоянный доступ. ссылка на исходную функцию, как в случае с переменной p
в примере выше.