3
votes

I'm quite new to flex/actionscript and I was wondering if there is an equivalent for php's (and other languages) FILE and LINE identifiers?

Basicly I want to do some custom error logging and would like to something like:

 var mymessage:String = 'Oops, a hiccup occured at ' + __FILE__ + ', line: ' + __LINE__; 

Where file and line would ofcourse be substituted for their values at compile time.

Is this possible?

3

3 Answers

3
votes

It's not directly possible, but there's a fairly usable workaround for personal testing

var stackTrace:String = new Error().getStackTrace();
if (stackTrace) {
    var mymessage:String = "Oops, a hiccup occurred " + stackTrace.split("\n")[1];
}

Adjust your abuse of getStackTrace to taste.

1
votes

To add to Cory's answer to the above. First add:

-define=CONFIG::debugging,true

to your library's compiler settings (next to the "-locale en_US" in "Additional Compiler Arguments"). Then use this quickie library:

package ddd
{
  public class Stack
  {
    protected static function str(val:*):String
    {
      if( val == null      ) return "<null>";
      if( val == undefined ) return "<undefined>";
      return val.toString();
    }

    protected static var removeAt :RegExp = /^\s*at\s*/i;
    protected static var matchFile:RegExp = /[(][)][\[][^:]*?:[0-9]+[\]]\s*$/i;
    protected static var trimFile :RegExp = /[()\[\]\s]*/ig;

    /* Must maintain number of stack levels, so that _stack can assume the 4th line of getStackTrace */
    private static function _stack( msg:String="", ...params ):String
    {
      var s   :String = new Error().getStackTrace();
      var func:String = "??";
      var file:String = "??";
      var args:String = null;
      if(s)
      {
        func = s.split("\n")[4];
        func = func.replace( removeAt, "" );
        var farr:Array  = func.match( matchFile );
        if( farr != null && farr.length > 0 ) file = farr[0].replace( trimFile, "" );
        func = func.replace( matchFile, "" );
      }
      for each( var param:* in params )
      {
        args = ( args == null ? "" : args.concat(",") );
        args = args.concat( str(param) );
      }
      return func + "(" + (args==null?"":args) + ")" + ( (msg!=null && msg!="") ? ":"+msg : "" ) + " at " + file;
    }

    /* Must maintain number of stack levels, so that _stack can assume the 4th line of getStackTrace */
    public static function stack( msg:String="", ...params ):String
    {
      params.unshift( msg );
      return _stack.apply( null, params );
    }

    /* Must maintain number of stack levels, so that _stack can assume the 4th line of getStackTrace */
    public static function pstack( msg:String="", ...params ):void
    {
      CONFIG::debugging {
        params.unshift(msg);
        trace( _stack.apply( null, params ) );
      }
    }
  }
}

And then you can just call:

Stack.pstack();

inside any function to print the stack location at that point, which looks like this:

package::classname/function() at /wherever/src/package/classname.mxml:999

Just remember to turn debugging to false before compiling for production, and all that will be left is an empty pstack call that does nothing - the guts will be conditional-compiled out.

0
votes

IMHO the line or file doesn't add to much information in Flex. I usually output class and method name and as my methods tend to be short, it usually is clear where something occurred.

If you find yourself with methods that are hundreds of lines long, you should rethink your coding style.