This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Find the name of a function
Started by skwerlman, 22 March 2014 - 05:42 AMPosted 22 March 2014 - 06:42 AM
I know that this is possible using the Lua debug library, but it doesn't look like CC implements it. Anyone know of a way to do this without requiring each function to set a name string?
Posted 22 March 2014 - 07:27 AM
nope. I think java functions give their names when you tostring() them, might just be certain built-in luaj functions, but nope, no getting lua function's names. They don't, strictly speaking, /have/ names, actually. Functions are first-class objects, the name is just a variable that references the function, and many variables can reference the same function.
The most common lua function syntax
is actually syntactic sugar, a convenience and aesthetic thing. The "natural" lua syntax is
The most common lua function syntax
function <name> (<args...>)
<body>
end
is actually syntactic sugar, a convenience and aesthetic thing. The "natural" lua syntax is
<name> = function(<args...>) <body> end
which makes the fact that the function name is just a variable holding the function more explicit.Edited on 22 March 2014 - 06:30 AM
Posted 22 March 2014 - 07:33 AM
What's the context of what you're trying to do? There might be an alternate way to do it.
Alternatively, you could do something like this:
It's a bit hacky, and it's not 100% sure to work, but it might.
Alternatively, you could do something like this:
function myFunction()
print('hi')
end
local func = myFunction --your reference to the function
for k, v in pairs(getfenv()) do
--you could also use _G, checking if k ~= 'func' is a litte hacky, but it'll probably work
if v == func and k ~= 'func' then
--v is the function name
end
end
It's a bit hacky, and it's not 100% sure to work, but it might.
Edited on 22 March 2014 - 07:49 AM
Posted 22 March 2014 - 08:28 AM
Basically, I have a function that gets passed an arbitrary function. I want to find the name of the variable that contains the passed function, if there is one. It would also be nice if I could handle anonymous functions, too.What's the context of what you're trying to do? There might be an alternate way to do it.
Alternatively, you could go something like this:function myFunction() print('hi') end local func = myFunction --your reference to the function for k, v in pairs(getfenv()) do --you could also use _G, checking if k ~= 'func' is a litte hacky, but it'll probably work if v == func and k ~= 'func' then --v is the function name end end
Edited on 22 March 2014 - 08:02 AM
Posted 22 March 2014 - 08:43 AM
You could do that, but there's no guarentee you'll find one (most user-defined variables don't end up in there, global or not), or even a guarentee that the function was ever specifically assigned to a variable at all.
To guess, are you trying to create a script that "resumes" other scripts by recording what they did and "replaying" it later? Again, more context would make it easier to help you.
To guess, are you trying to create a script that "resumes" other scripts by recording what they did and "replaying" it later? Again, more context would make it easier to help you.
Posted 22 March 2014 - 08:56 AM
I'm trying to augment error messages in certain instances by not only specifying where the error occurred (as in the default scheme) but also what caused the error. Knowing the name of a function (again, if there is one) is important because I'd like to specify which of several functions (as in the below example) passed caused the error.You could do that, but there's no guarentee you'll find one (most user-defined variables don't end up in there, global or not), or even a guarentee that the function was ever specifically assigned to a variable at all.
To guess, are you trying to create a script that "resumes" other scripts by recording what they did and "replaying" it later? Again, more context would make it easier to help you.
function foo( ... )
local tFuncs = { ... }
local tFuncNames
for i=1, #tFuncs do
--Insert code to find function name here
tFuncNames = sFuncName -- where sFuncName is the name of the function
assert(type(tFuncs[i]) == 'function', sFuncName..' is not a function')
end
--The rest of the code
end
Posted 22 March 2014 - 09:03 AM
are you aware of pcall and the error function's ability to take a 2nd argument that is how many levels up to locate the error?
examples..
and pcall can be used to intercept and re-throw errors in code you don't control (and so can't modify the error() calls on)
examples..
function myFunc(args)
error("You gave me bad args!",2)
--the 2 makes it throw the error with the line number where myFunc was called
--instead of the line number of this error() call
end
and pcall can be used to intercept and re-throw errors in code you don't control (and so can't modify the error() calls on)
res={pcall(somebodyElsesFunction,args)}
if res[1] then
--res[2] through res[#res] will be the returned values of somebodyElsesFunction,
--to be used normally or whatever
else
--res[1] being false means an error, and res[2] is the error message
error("error in somebodyElsesFunction : "..res[2],someLevel)
--rethrow with level as in last example
end
Edited on 22 March 2014 - 08:04 AM
Posted 22 March 2014 - 09:05 AM
Yes, I am, but I'd also like to give the name of the offending argument. As I said, I'm looking to improve the current error system.are you aware of pcall and the error function's ability to take a 2nd argument that is how many levels up to locate the error?
examples..function myFunc(args) error("You gave me bad args!",2) --the 2 makes it throw the error with the line number where myFunc was called --instead of the line number of this error() call end
and pcall can be used to intercept and re-throw errors in code you don't control (and so can't modify the error() calls on)res={pcall(somebodyElsesFunction,args)} if res[1] then --res[2]-res[#res] will be the returned values of somebodyElsesFunction, to be used normally ot whatev) else --res[1] being false means an error, and res[2] is the error message error("error in somebodyElse'sFunction : "..res[2],someLevel) --rethrow with level as in last example end
Posted 22 March 2014 - 09:08 AM
why would yo want to throw the name of the variable passed as an argument instead of the logical name of the argument it was passed as? if function foo(derp) errors for a bad derp, just throw "bad derp" with the error level such that it gives the line number where they called foo? surely the leap from derp to whatever variable they passed is not an unreasonable ask for the programmer?
Edited on 22 March 2014 - 08:10 AM
Posted 22 March 2014 - 09:16 AM
Because sometimes, as in the example above, you don't know how many variables there are, and it may even be that the programmer is dynamically generating and passing the variables, so they don't even know, and then it's a debugging nightmare. If I could get the name, I could tell the programmer where to look with greater precision than otherwise, making their job that much easier.why would yo want to throw the name of the variable passed as an argument instead of the logical name of the argument it was passed as? if function foo(derp) errors for a bad derp, just throw "bad derp" with the error level such that it gives the line number where they called foo? surely the leap from derp to whatever variable they passed is not an unreasonable ask for the programmer?
Posted 22 March 2014 - 09:25 AM
Have you seen this? I haven't really seen how the code works, but it looks like it's along the lines of what you want.
http://www.computerc...-file-extracts/
Avoid posting because it's been dead almost a year now.
http://www.computerc...-file-extracts/
Avoid posting because it's been dead almost a year now.
Edited on 22 March 2014 - 08:29 AM
Posted 22 March 2014 - 09:27 AM
That is so much better than what I was thinking. Great find!Have you seen this? I haven't really see how the code works, but it looks like it's along the lines of what you want.
http://www.computerc...-file-extracts/
Avoid posting because it's been dead almost a year now.
EDIT: It appears to be broken… I can't seem to load any of the functions.
Edited on 22 March 2014 - 08:53 AM
Posted 22 March 2014 - 10:01 AM
@oeed: Your first idea works, and very well too. But, for whatever reason, it can't see functions declared as local, regardless of getfenv's scope. I'm gonna see if it works with other data types.
EDIT: It works with all variables, but with the same restrictions. It can't see local variables.
EDIT: It works with all variables, but with the same restrictions. It can't see local variables.
Edited on 22 March 2014 - 09:04 AM