debug.getparams - Get the names of a function's arguments

ChewGum was asking if this was possible. I promptly replied no, but then thought again.

This was the result:
[lua]
function debug.getparams(f)
local co = coroutine.create(f)
local params = {}
debug.sethook(co, function()
local i, k = 1, debug.getlocal(co, 2, 1)
while k do
if k ~= “(*temporary)” then
table.insert(params, k)
end
i = i+1
k = debug.getlocal(co, 2, i)
end
error(“end”)
end, “c”)
local res, err = coroutine.resume(co)
if res then
error(“The function provided defies the laws of the universe.”, 2)
elseif string.sub(tostring(err), -7) ~= “end” then
error("The function failed with the error: "…tostring(err), 2)
end
return params
end
[/lua]

Example usage:
[lua]
function f(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,…)
print(x+1,y,z) – this proves that the code within the function does not run
end
for k,v in pairs(debug.getparams(f)) do
print(“l:”, k, v)
end
–[[ Output:
l: 1 a
l: 2 b
l: 3 c
l: 4 d
l: 5 e
l: 6 f
l: 7 g
l: 8 h
l: 9 i
l: 10 j
l: 11 k
l: 12 l
l: 13 m
l: 14 n
l: 15 o
l: 16 p
l: 17 q
l: 18 r
l: 19 s
l: 20 t
l: 21 u
l: 22 v
l: 23 w
l: 24 x
l: 25 y
l: 26 z
l: 27 arg
]]
[/lua]

Or just a single liner:
[lua]
print(table.concat(debug.getparams(f), ", "))
[/lua]

Handy override of print:
[lua]
do
local oprint = print
function print(…)
local args = {…}
for i = 1, #args do
local arg = args*
if type(arg) == “function” then
local name = debug.getinfo(arg).name
args* = (name and name ~= “” and name or tostring(arg))…"("…table.concat(debug.getparams(arg), “,”)…")"
end
end
oprint(unpack(args))
end
end
[/lua]

Please inform me of any bugs.

Thanks to ChewGum for the inspiration and annoyance.
Yay for the Lua Manual.

Enjoy!

Very nice, I really love that. :smiley:

Clever. But “defies”, not “defys”.

What are you talking about :ninja:

I take it Garry fixed them. What exactly is the point of using one, though?

what

Wrong thread?

Ohshit, I just realized it sound like I have no clue what I was talking about. :downswords: I was talking about coroutines.

Well, they seem to work perfectly with this.

Bravo.

This is really cool.

This seems to work on some, but not others:



] lua_run_cl print(table.concat(debug.getparams(PrintTable), ", "))
t, indent, done
] lua_run_cl print(table.concat(debug.getparams(Derma_StringRequest), ", "))
:17: bad argument #1 to 'resume' (Vector expected, got thread)


Edit: And now it works perfectly. I bet that as soon as I stop debugging it and actually try to use it, it’ll error again.

can’t do inlines.
[lua]function snib(f)
print(table.concat(debug.getparams(f), ", "))
end
snib(function(a,b,c) end);

print(table.concat(debug.getparams(function(a, waffke, plib) end), ", "))
[/lua]
both print an empty line.



> print(table.concat(debug.getparams(function(a,b,c) end), ", "))

> print(table.concat(debug.getparams(function(a,b,c) x=y end), ", "))
a, b, c


It appears Lua doesn’t bother with the localising of the arguments if the function has no code.

This is awesome :smiley:

Thanks to all for testing this.
I hope it makes someone’s life easier.

I optimised it a slight bit, even though it won’t make much of a difference.

If anyone has an idea for another debug function they’d like, please tell.

I’m confused, I thought coroutines were broke. :l

Can you lighten my on this subject?

Oh man, this is going to be extremely useful. I could see it being used for hacks… Not that i will or ever have used them :ninja:
But seriously, epic man, epic.

Give me one example for which this could be used for a hack. All of this info is publically accessable anyhow, you can just find it with a grep of your dua files :l

Well, it would save th whole trawl through the Dua files (or the search), among other things.

A very cool function Deco, I can’t think of any uses for it right now though.