can an actionscript function find out its own name?

10,337

Solution 1

I use the following:

private function getFunctionName(e:Error):String {
    var stackTrace:String = e.getStackTrace();     // entire stack trace
    var startIndex:int = stackTrace.indexOf("at ");// start of first line
    var endIndex:int = stackTrace.indexOf("()");   // end of function name
    return stackTrace.substring(startIndex + 3, endIndex);
}

Usage:

private function on_applicationComplete(event:FlexEvent):void {
    trace(getFunctionName(new Error());
}

Output: FlexAppName/on_applicationComplete()

More information about the technique can be found at Alex's site:

http://blogs.adobe.com/aharui/2007/10/debugging_tricks.html

Solution 2

I've been trying out the suggested solutions, but I ran into trouble with all of them at certain points. Mostly because of the limitations to either fixed or dynamic members. I've done some work and combined both approaches. Mind you, it works only for publicly visible members - in all other cases null is returned.

    /**
     * Returns the name of a function. The function must be <b>publicly</b> visible,
     * otherwise nothing will be found and <code>null</code> returned.</br>Namespaces like
     * <code>internal</code>, <code>protected</code>, <code>private</code>, etc. cannot
     * be accessed by this method.
     * 
     * @param f The function you want to get the name of.
     * 
     * @return  The name of the function or <code>null</code> if no match was found.</br>
     *          In that case it is likely that the function is declared 
     *          in the <code>private</code> namespace.
     **/
    public static function getFunctionName(f:Function):String
    {
        // get the object that contains the function (this of f)
        var t:Object = getSavedThis(f); 

        // get all methods contained
        var methods:XMLList = describeType(t)..method.@name;

        for each (var m:String in methods)
        {
            // return the method name if the thisObject of f (t) 
            // has a property by that name 
            // that is not null (null = doesn't exist) and 
            // is strictly equal to the function we search the name of
            if (t.hasOwnProperty(m) && t[m] != null && t[m] === f) return m;            
        }
        // if we arrive here, we haven't found anything... 
        // maybe the function is declared in the private namespace?
        return null;                                        
    }

Solution 3

Heres a simple implementation

    public function testFunction():void {
        trace("this function name is " + FunctionUtils.getName()); //will output testFunction
    }

And in a file called FunctionUtils I put this...

    /** Gets the name of the function which is calling */
    public static function getName():String {
        var error:Error = new Error();
        var stackTrace:String = error.getStackTrace();     // entire stack trace
        var startIndex:int = stackTrace.indexOf("at ", stackTrace.indexOf("at ") + 1); //start of second line
        var endIndex:int = stackTrace.indexOf("()", startIndex);   // end of function name

        var lastLine:String = stackTrace.substring(startIndex + 3, endIndex);
        var functionSeperatorIndex:int = lastLine.indexOf('/');

        var functionName:String = lastLine.substring(functionSeperatorIndex + 1, lastLine.length);

        return functionName;
    }

Solution 4

The name? No, you can't. What you can do however is test the reference. Something like this:

function foo()
{
}

function bar()
{
}

function a(b : Function)
{
   if( b == foo )
   {
       // b is the foo function.
   }
   else
   if( b == bar )
   {
       // b is the bar function.
   }
}
Share:
10,337
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    given the following

    function A(b:Function)   { }
    

    If function A(), can we determine the name of the function being passed in as parameter 'b' ? Does the answer differ for AS2 and AS3 ?

  • BefittingTheorem
    BefittingTheorem about 15 years
    I would say be careful using this in your system design, it is pretty brittle code, as in, if someone at Adobe decides to rephrase their stack trace message your code breaks. So maybe ask yourself if you really need to know the functions name to solve the problem you have.
  • Admin
    Admin about 15 years
    Agreed. I use it primarily for debugging, and not so much lately since I can step through code with Flex Builder Pro.
  • Josh Tynjala
    Josh Tynjala about 15 years
    You can't get the caller, but you do have a reference to the callee.
  • back2dos
    back2dos over 14 years
    very cool idea ... but works only in debug player!!! if that is sufficient, ok, but in general this still does not solve the problem ....
  • Atorian
    Atorian over 11 years
    With Air 3.5 & Flash 11.5 it is now possible to get a stack trace with release builds. I agree that this method is risky - a small change in the stack trace string format could easily break code, but it works, and works well.
  • Art
    Art over 10 years
    Good approach, but getSavedThis() works only in debug versions of flash player.
  • Hudson
    Hudson over 9 years
    Thanks for this, and in case anyone else has trouble finding the packages: import flash.utils.describeType; import flash.sampler.getSavedThis;