Getting a functions name as a string?

Hey, I’m looking to find a way to get the name of a function but I have no idea what I should do. All I know is I should be using the debug library.




function DivideByTwo( number )
	return number / 2
end



If I do print( DivideByTwo ) it will come out with function: blah blah blah obviously, but I’m looking to get the actual name like DivideByTwo, thanks.

This pretty much explains everything you need.

The main functions you’re going to use are debug.getlocal and debug.getupvalue

I still don’t understand how you get the name of the function, I’m still getting function: 0x31e082b8 using that.

This isn’t possible in pure Lua - you can only get the name of functions on the stack, and getlocal would only give you the name you used for the argument, rather than the actual defined name of the function.

i suppose it depends on how disgusting you want to be
you can get lua functions like so:

[LUA]
local function GetFunctionName( func )
local info = debug.getinfo( func )
if info.what == “C” then return “C Function” end

local f = file.Open( info.source:sub( 2 ), "r", "MOD" )
local str = f:Read( f:Size() )
local exp = string.Explode( "

", str )

local funcline = exp[info.linedefined]
local ind = funcline:find( "function " )

if not ind then return "Failed to find funcline" else ind = ind + 9 end
local name = funcline:sub( ind )

return name:sub( 1, name:find( "%(" ) - 1 )

end

concommand.Add( “vv”, function() local v = IsValid print( GetFunctionName( v ), GetFunctionName( Either ) ) end )
[/LUA]
but it’s fairly expensive, and should only be used for debugging or very rarely

im sorry :v

And then you get to add support for declaring your functions in alternate forms:


x = function( ) end --This would probably still work
x = CompileString( some_code_here )
RunString( "code that defines a function" ) --Maybe?

It will work a fair amount of the time, but as soon as you step away from normal declarations it blows up.

yeah, you’re not going to get it perfect. i suppose for the average function it will do as well

[editline]11th May 2014[/editline]

Here it is now, should support most everything but C and CompileFile( couldn’t get anything to compile )
also runstring, obviously
[LUA]
local compile_string = compile_string ~= nil and compile_string or CompileString
local compiledfuncs = compiledfuncs ~= nil and compiledfuncs or {}
CompileString = function( str, handle, errors )
local stack = debug.getinfo( 2 )
compiledfuncs[handle] = { stack.currentline, stack.short_src }

return compile_string( str, handle, errors )

end

local cache = cache ~= nil and cache or {}
local function GetFunctionName( func )
if cache[func] then return cache[func] end

if not func then return "RunString/Invalid function" end

local info = debug.getinfo( func )
if info.what == "C" then return "C Function" end

if not info.source:find( "/" ) then
	local handle = info.short_src
	if compiledfuncs[handle] then
		local inf = compiledfuncs[handle]
		local msg = Format( "CompileString/File Compiled function. Handle '%s', Defined on line %i in %s", handle, inf[1], inf[2] )
		cache[func] = msg
		return msg
	else
		local msg = Format( "CompileString/File Compiled function. Handle '%s'", handle )
		cache[func] = msg
		return msg
	end
end

local f = file.Open( info.source:sub( 2 ), "r", "MOD" )
local str = f:Read( f:Size() )
local exp = string.Explode( "

", str )

local funcline = exp[info.linedefined]
local ind = funcline:find( "function" )

if not ind then
	local msg = Format( "Failed to find funcline, file defined %s", funcline )
	cache[func] = msg
	return msg
else ind = ind + 9
end
local name = funcline:sub( ind )

local brac = name:find( "%(" )
if not brac then 
	local msg = Format( "Variable Function, No name. Defined in %s on line %s", info.source:sub( 2 ), info.linedefined ) 
	cache[func] = msg
	return msg
end
name = name:sub( 1, brac - 1 )

cache[func] = name
return name

end

concommand.Add( “func_name”, function()
local comps = CompileString( “function testf() print( ‘hi’ ) end”, “bbj” )
local var = function() end

print( "RunString:", GetFunctionName( RunString( "function testf2() end" ) ) ) 
print( "-

" )
print( “Variable Function:”, GetFunctionName( var ) )
print( "-
" )
print( “CompileString:”, GetFunctionName( comps ) )
print( "-
" )
print( “Module:”, GetFunctionName( net.Receive ) )
print( "-
" )
print( “Normal Function:”, GetFunctionName( IsValid ) )
end )
[/LUA]