2011-01-19 28 views

Respuesta

26

Use arguments.callee para obtener una referencia a la función actual.

Si desea obtener el nombre de la función, es un poco más complicado: todas las funciones se tratan como cierres de métodos (fragmentos de código que pueden transmitirse como argumento), por lo que no poseen una referencia a un adjunto tipo de clase, ni tienen un "nombre actual".

Sin embargo, si (y única si) el método es pública, y que desea obtener el nombre del método de la declaración de la clase de un objeto de instancia que contiene el método, puede utilizar describeType:

public function someFunction() : void { 
    var callee:Function = arguments.callee; 
    trace (getFunctionName(callee, this)); // ==> someFunction 
} 

private function someOtherFunction() : void { 
    var callee:Function = arguments.callee; 
    trace (getFunctionName(callee, this)); // ==> not found 
} 

private function getFunctionName (callee:Function, parent:Object):String { 
    for each (var m:XML in describeType(parent)..method) { 
     if (parent[[email protected]] == callee) return [email protected]; 
    } 
    return "not found"; 
} 

Tenga en cuenta que esto no funcionaría cuando llame al someFunction() desde un constructor, porque el objeto no está completamente instanciado: describeType(this) en un constructor causaría un error de compilación.

+1

nota rápida: si quieres poder usar esto de otra clase, tienes que reemplazar 'this [m. @ Name]' con 'parent [m. @ Name]' –

+0

Eso fue en realidad un error. Gracias por llamar mi atención, @kriswelsh – weltraumpirat

2

Probablemente no podrá obtener el nombre de una función, porque no realmente tienen un "nombre" como tal. Al igual que sus variables no tienen nombres. Son solo indicadores de un objeto.

Obtener el nombre no tiene sentido, en parte por el siguiente ejemplo:

function foo():void 
{ 
    //get function name. 
} 
var bar:Function = foo; 
bar(); 

Una función es igual que cualquier otro objeto/variable. ¿Qué "nombre" encontraría esta función? "foo"? o "barra"? Tanto foo como la barra hacen referencia a la misma variable del tipo Function.

Una mejor manera de manejar esto sería pasar algo en la función como argumento:

function foo(myName:String):void 
{ 
    trace(myName); 
} 

Puede sin embargo, obtener una referencia a la función actual utilizando el arguments.callee :)

+0

Creo que es muy difícil de creer lo que dices. Incluso cuando compilo una versión de lanzamiento de la aplicación Flex con declaraciones de rastreo suprimidas y sin vista de origen, si se produce un error no controlado, Flash Player me proporcionará una secuencia de métodos _por nombre_, incluyendo la clase asociada y su paquete respectivo. Eso me sugiere que la función _name_info está codificada definitivamente en el swf, y por lo tanto debería ser accesible de alguna manera. – merv

+3

... la diferencia radica en que la pila se rastrea "desde el exterior", como una operación introspectiva, que permite que se conozca toda la jerarquía de clase y objeto del programa, mientras que esto es imposible desde dentro de un cuerpo de función. Siempre puedes tener algún tipo de "pila personalizada" que rastrea tu objeto y las llamadas a un método, si quieres tener una funcionalidad similar. – weltraumpirat

+0

@weltraumpirat - Gracias por aclarar eso. – merv

5

Lo acabo de hacer con un seguimiento de pila, que es lo que muestra el depurador de Flash Player cuando se produce un error no controlado. Aquí está mi aplicación:

function blah() 
{ 
    var e:Error = new Error(); 
    var s:String = e.getStackTrace(); 
    var functionName:String = s.slice(s.indexOf('/')+1, s.indexOf('(')); 
    trace(functionName); //blah 
} 

Usted va a necesitar para hacer el análisis de la cadena un poco más elegante, si quieres hacer de esto una función separada. Pero el nombre de la función definitivamente está en el rastro de la pila.

Editar: advertencia importante

El AS3 Lang Ref dice que el método getStackTrace sólo funciona en las versiones de depuración de Flash Player/AIR, y volverá null lo contrario. Entonces definitivamente esta no es una solución desplegable. Lo siento.

+1

A partir de la versión 11.5 y posterior está disponible en versiones sin debugger. Cita, 'Para Flash Player 11.4 y anteriores, y AIR 3.4 y versiones anteriores, los rastreos de pila solo están disponibles cuando el código se ejecuta en la versión depuradora de Flash Player o AIR Debug Launcher (ADL). En las versiones sin depuración de esos tiempos de ejecución, llamar a este método devuelve nulo. - http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Error.html –

0

cuando necesitaba identificaciones para las funciones de aplicación para mi sistema de eventos no encontré una manera de acceder a una name de una función no anónimo pasa como argumento por lo que tenía que escribir un envoltorio que nada, excepto almacena la Function y su ID

2

para sacar esto adelante en ActionScript 2, que tenía que hacer recientemente con un poco de código heredado

function getFunctionName(func:Function):String 
{ 
    for(var prop in this) 
    { 
    if(this[prop] == func) 
    { 
     return prop; 
     break; 
    } 
    } 
} 

y utilizarlo algo como esto

trace(getFunctionName(arguments.callee)); 
Cuestiones relacionadas