[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Please translate this easy snip of C++ to Lua
- From: Rici Lake <lua@...>
- Date: Wed, 8 Dec 2004 20:18:33 -0500
On 8-Dec-04, at 5:47 PM, Philip Plumlee wrote:
Luists:
Ogle this awesome snip of C++:
#define TRACE_(x) cout << #x ": " << x << endl
When you use that like this...
TRACE_(y + z);
TRACE_(strAnimals);
TRACE_(__LINE__);
...the program emits this:
y + z: 12
strAnimals: Lemmings
__LINE__: 69
Mighty healthy and easy to write debug statements with, huh? Saves a
lot
of keystrokes, huh?
Nice.
Here's how to do it in Lua:
local function getvalue(_, k)
local level = 1
repeat level = level + 1
until debug.getlocal(level, 2) ==
"thisIsWhyIdentifyingCallframesByDepthIsEvil"
level = level + 1
for i = 1, 1e6 do
local name, val = debug.getlocal(level, i)
if name == k then return val end
if not name then break end
end
local func = debug.getinfo(level, "f").func
for i = 1, 1e6 do
local name, val = debug.getupvalue(func, i)
if name == k then return val end
if not name then break end
end
return getfenv(level)[k]
end
local function show(_, ...)
for i = 1, arg.n do arg[i] = tostring(arg[i]) end
return table.concat(arg, ', ')
end
function TRACE_(s)
local thisIsWhyIdentifyingCallframesByDepthIsEvil = "but there is a
hack"
local env = setmetatable({}, {__index = getvalue})
local chunk, msg = loadstring("return "..s)
if chunk then
setfenv(chunk, env)
msg = show(pcall(chunk))
end
print(s..": "..msg)
end
---- Example, showing all three possibilities
> function foo(a)
>> local function bar(x, y)
>> if a then
>> TRACE_[[a, x+y, author]]
>> end
>> end
>> return bar
>> end
>
> author = "Rici"
> closure = foo "The answer is"
> closure(17, 25)
a, x+y, author: The answer is, 42, Rici
-- Here is why counting levels is necessary (the usual answer is 5,
-- so the search could have started from there)
> s = "Not hidden by TRACE_"
> TRACE2_[[s]]
s: Not hidden by TRACE_
> TRACE_[[(function() return s end)()]]
(function() return s end)(): Not hidden by TRACE_
-- Simply setting level to 5 in getvalue results in the following:
> TRACE2_[[s]]
s: Not hidden by TRACE_
> TRACE2_[[(function() return s end)()]]
(function() return s end)(): (function() return s end)()