Tuesday, November 30, 2010

Extending AS3 trace

On a previous post (debugging spaghetti code) I mentioned it's important to know where a specific function is being called.
From Adobe, this is the description of what the function trace does:
Displays expressions, or writes to log files, while debugging.
We can trace anything anywhere in our code, however, as mentioned before, how do we know where? we could then specify this in each trace call, for example:
trace('MyClass - ' + someValueToTrace);
trace('MyClass - ' + someOtherValue);
Right, instead of writing the object's name in every call, we could have a private function to do this:
private function debug(objectToTrace : Object) : void
{
trace('MyClass' + objectToTrace);
}
Then, instead of calling 'trace(blah)' we use 'debug(blah)' which will include the class name. For example:
debug(someValue);
// outputs: 'MyClass - someValue'
Advantages? well, if in case we don't want to trace anything any more, we just comment out the 'trace' line in our code rather than deleting every single call to debug in that class...

Cool! now we know where are we using 'trace'.

Can we extend it? sure thing! and this is my solution:

- Create a class in your utils package, name it Debug.as.
- Create a static function to trace the name of the caller plus any parameter.
Code:
package com.mysite.core.utils
{
import flash.utils.getQualifiedClassName;

public class Debug
{
/**
* // Writes in the flashlog the name of the object calling this function and any number of parameters

* Debug.print(this, someValue, someOtherValue);
*/
public static function write(caller : Object, ...arguments) : void
{
var objectString : String = getClassName(caller);
trace(objectString + ' - ' + arguments);
}

private static function getClassName(object : Object) : String
{
var className : String = getQualifiedClassName(object);
return className.slice(className.lastIndexOf('::'));
}

}

}
If we don't use the second function (getClassName), the output would be '[object MyClass]' so that's why we slice a string to get only the very class name.
Now you can call Debug.write instead of trace in the debug function on every class:
private function debug(objectToTrace : Object) : void
{
Debug.write(this, objectToTrace);
}
// use debug(objectToTrace) instead of trace(objectToTrace)
Sweet! :)

No comments: