views:

114

answers:

4

Hi all,

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?

A: 

Actionscript 3 is compiled, it won't hold the line information.

BUT If you are using a debug version of the flash player, you can get the line number with the Error function getStackTrace()

You can get the swf path using:

var urlPath:* = ExternalInterface.call("window.location.href.toString()");

OR

var urlPath:String = loaderInfo.url;
M28
Thanks for your input, the stacktrace is usefull, but limited because of the debugger requirement.I know actionscript is compiled, this is why subtitution should take place at compile time (if memory serves, this is achievable in c++), so that the compiled swf would hold the line and file information as strings.
Douwe
Maybe if you really want it you can add "lineNumber++" at the end of every line, lol.
M28
It would be nice if the compiler would do that for me :)
Douwe
I didn't get that `ExternalInterface` part - it just gives the html page url; nothing to do with the line number.
Amarghosh
It has nothing to do with the line number, it gets the swf url.
M28
@M28 if it has nothing to do with the line number, maybe you should change your answer where it says "you can get the line number using" then.
davr
Oh sorry, I didn't see that error, thanks anyway :)
M28
Sorry, but it doesn't follow that "as being compiled" implies that file/line number information isn't available. It's available in C, for example.
David Wolever
+3  A: 

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.

Cory Petosky
...not directly possible... :( I was afraid that would be the case, since google didn't come up with anything. Thanks for the heads up.
Douwe
@Douwe: stackTrace works in non-debug versions, it will give you class and method names, but not line number. Method name hopefully will be enough to trace it down, if you have 100+ line methods then that's a separate problem :)
davr
I thought that was the case, but the docs said it returns `null` and I didn't have time to confirm/deny. Thanks for the heads up davr.
Cory Petosky
I'm gonna test that Davr, thanks. The main reason I was after filenames and linenumbers is that the centralized logging app we already use for other apps takes them as input, so I wanted them for completion and for not having to redo parts of the logging app.
Douwe
This one is sure a killer !!!
Akash Kava
A: 

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.

ilikeorangutans
A: 

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.

eruciform
anything beyond this, like "logging levels", and you're making your own logging interface, which in my experience is a huge rabbit hole that rarely pays off in time spent. use the standard stuff that comes with the system. i just like this because the call is so small and stupid that you can put it in one-liner functions without making them scroll far off the right.
eruciform