如何在lua中为所选函数执行其他代码

时间:2016-01-20 09:22:46

标签: lua

是否有任何干净而优雅的方式将代码“插入”lua中的现有函数? 问题是我们有一个包含许多函数的表,我们必须对其参数及其结果进行简单的记录。对于对这些行进行日志记录的行进行复制的明显解决方案似乎并不合适,而且会耗费时间。 我试图使用metatables机制,即创建表作为包装器,但我找不到从其级别执行代码的方法:

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

或许这种做法完全错了?也许已经存在一种跟踪/记录我不知道的函数调用的机制?

1 个答案:

答案 0 :(得分:0)

考虑到你的初步方法,一种方法就是这样:

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()来调用它,请在local wrapper = function()中修改包装器。