如何在lua中为所选函数执行附加代码
有没有干净优雅的方法将代码“导入”到lua中的现有函数中? 问题是我们有一个包含许多函数的表,我们必须对它们的参数和结果执行简单的日志记录。显而易见的解决方案是复制粘贴将执行日志记录到每一行的行,这似乎不正确,而且会很耗时。 我试图使用元表机制,即创建一个充当包装器的表,但我找不到从其级别执行代码的方法:如何在lua中为所选函数执行附加代码,lua,Lua,有没有干净优雅的方法将代码“导入”到lua中的现有函数中? 问题是我们有一个包含许多函数的表,我们必须对它们的参数和结果执行简单的日志记录。显而易见的解决方案是复制粘贴将执行日志记录到每一行的行,这似乎不正确,而且会很耗时。 我试图使用元表机制,即创建一个充当包装器的表,但我找不到从其级别执行代码的方法: log = function(msg) trace(msg) end mapl = {} --wrapper table mt = { __index = map; -- map
log = function(msg) trace(msg) end
mapl = {} --wrapper table
mt = {
__index = map; -- map is the original table with many methods
-- is there a way to call log function here?
}
setmetatable(mapl, mt)
mapl:getMap(params) -- call to a getMap function in map via mapl wrapper
或者这种方法完全错误?也许已经有一种机制可以跟踪/记录我不知道的函数调用了?考虑到您最初的方法,一种方法是这样的:
local log = function(func_name, ...)
print("Calling "..func_name.." with args:")
for i,v in ipairs {...} do
print(i,v)
end
end
-- original map with functions to cover
local map = {
getMap = function() print "original getMap" end,
setNode = function() print "original setNode" end
}
-- logged interface
local mapl = {}
-- helper returning new logging wrapper
local function grab_args(_, func_name)
local func = map[func_name]
-- sanity check
if type(func) == "function" then
local wrapper = function(_, ...)
log(func_name, map, ...)
return func(map, ...)
end
-- cache wrapper for further usage
mapl[func_name] = wrapper
return wrapper
end
-- just return non-function values from map
return func
end
-- setup interface
setmetatable(mapl, {__index = grab_args})
-- test logging
mapl:getMap(1,2,3)
mapl:setNode(42)
关于样品的几点注释。您使用冒号将函数调用为
mapl:getMap()
。因此,在实际调用原始函数时,此示例将mapl
替换为map
。如果需要使用点调用它,mapl.getMap()
,在localwrapper=function()
中修改包装器的创建,考虑到您最初的方法,一种方法如下:
local log = function(func_name, ...)
print("Calling "..func_name.." with args:")
for i,v in ipairs {...} do
print(i,v)
end
end
-- original map with functions to cover
local map = {
getMap = function() print "original getMap" end,
setNode = function() print "original setNode" end
}
-- logged interface
local mapl = {}
-- helper returning new logging wrapper
local function grab_args(_, func_name)
local func = map[func_name]
-- sanity check
if type(func) == "function" then
local wrapper = function(_, ...)
log(func_name, map, ...)
return func(map, ...)
end
-- cache wrapper for further usage
mapl[func_name] = wrapper
return wrapper
end
-- just return non-function values from map
return func
end
-- setup interface
setmetatable(mapl, {__index = grab_args})
-- test logging
mapl:getMap(1,2,3)
mapl:setNode(42)
关于样品的几点注释。您使用冒号将函数调用为
mapl:getMap()
。因此,在实际调用原始函数时,此示例将mapl
替换为map
。如果需要用点调用它,mapl.getMap()
,在localwrapper=function()
中修改包装器的创建!这就是我要找的。不幸的是,对于我来说,参数似乎没有传递给元表中的grab_args函数。在grab_args(u,func_name,…)中,“…”始终为零。调用eample时,“未通过”是什么意思。mapl:getMap(1,2,3)我希望将1,2,3传递给grab_args,这样我就可以使用。。。作为param。相反地。。。始终为零。已通过。可能你们已经修改了示例,因为我在发布答案之前做了测试,这里是到ideone的链接:还要注意,因为你们用冒号调用函数,第一个参数将是存储函数的表,在示例中,我用map替换了mapl,因为函数可能依赖于此。啊,对不起,你们并没有获取参数来获取参数。实际上,该函数只会为该函数创建(并缓存)新的包装器。实际调用函数时将捕获实际参数。忽略抓取参数中的…
。我更新了样品,太棒了!这就是我要找的。不幸的是,对于我来说,参数似乎没有传递给元表中的grab_args函数。在grab_args(u,func_name,…)中,“…”始终为零。调用eample时,“未通过”是什么意思。mapl:getMap(1,2,3)我希望将1,2,3传递给grab_args,这样我就可以使用。。。作为param。相反地。。。始终为零。已通过。可能你们已经修改了示例,因为我在发布答案之前做了测试,这里是到ideone的链接:还要注意,因为你们用冒号调用函数,第一个参数将是存储函数的表,在示例中,我用map替换了mapl,因为函数可能依赖于此。啊,对不起,你们并没有获取参数来获取参数。实际上,该函数只会为该函数创建(并缓存)新的包装器。实际调用函数时将捕获实际参数。忽略抓取参数中的…
。我已经更新了样品。