martes, 17 de mayo de 2016

spying on lua function calls

Following on lua, there's been some trick I've been using for some time, and it's quite useful and (as usual), doable with tiny piece of code.

If we want to have a trace of function calls with their parameters and results, there's a super easy way to do it in lua.  The functionality is basically inspired by lisp's trace or elisp's trace-function.  The code is ridiculously simple, it's a basic case of rewriting key-values in modules and wrapping functions.

local function make_tracer()
  local indent = ""
  return function (mod, f_name)
    local old = mod[f_name]
    return function (...)
      print( string.format("%sCall: %s: params: ", indent, f_name), ...)
      indent = indent .. "   "
      local ret = {old(...)}
      indent = string.sub(indent, 4)
      print(string.format("%sRetn: %s: ",indent, f_name), unpack(ret))
      return unpack(ret)
    end
  end
end
local trace = make_tracer()
... 
for m,_ in pairs(M) do M[m]=trace(M, m) end

It's great that with so simple code we can have a basic debugging tool like this one (btw, this tool is probably not very robust if we put coroutines in the mix, but for simple cases it works quite well).  All this is possible because lua embraces the Universal Design Pattern.