[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: wrapping functions
- From: "John Belmonte" <jvb@...>
- Date: Fri, 4 May 2001 18:16:02 +0900
Here is some info about wrapping Lua functions. It seems to validate the
general usefulness of the expand function I outlined in a previous post
"vararg asymmetry". No chance of having that added to baselib?
Given a function, I'd like to wrap it inside some pre and post-processing.
This is often useful for debugging or synchronization. Here is a simple
example wrapping the global sin function:
function sin(x)
pre_function()
local y = %sin(x)
post_function()
return y
end
However this is not very general. It would be nice to wrap functions
without knowing the details of their inputs and outputs. Furthermore Lua
functions may have a variable number of inputs or outputs (for example,
strfind).
Accounting for this, pre-processing is no problem. Here I'm wrapping an
arbitrary global function X:
function X(...)
pre_function()
return call(%X, arg)
end
But what about the post-processing? We need a way to temporarily store all
the return values of the wrapped function. The only option seems to be to
store them in a table. Here's a convenient function for that:
function compress(...)
return arg
end
That was easy, but we'll also need an expand function to convert the table
back into individual return values. Such a function was the topic of my
"vararg asymmetry" post. It can be implemented recursively in Lua or
iteratively using the C API. Using these functions, here is the final
version of the function wrapping:
function X(...)
pre_function()
local results = compress(call(%X, arg))
post_function()
return expand(results)
end
If this all seems esoteric, here is a practical example. I'd like to wrap
dofile and have it load relative to the current script, whose path is held
in a variable SCRIPT_NAME. It handles recursive calls by saving and
restoring the path:
function dofile(name)
local temp = SCRIPT_NAME
SCRIPT_NAME = DirectoryPart(SCRIPT_NAME).."/"..name
local results = compress(%dofile(SCRIPT_NAME))
SCRIPT_NAME = temp
return expand(results)
end
-John