assert in ActionScript 3
In the old days of Java, one often complained about the lack of an assert statement. Once I even wrote an “Assert” class that threw a runtime exception (based on a debug flag), but I didn’t end up using it all that much due to performance constraints.
Eventually Java did get a native assert statement.
Now we’re finding ourselves in a similar situation with ActionScript 3. My program has grown complex enough that I need to sprinkle it with assertions in certain portions. This is becoming important as more developers start working on the same piece of code. It’s good to document the pre-conditions and post-conditions in source comments, but, let’s face it, nobody reads comments until they actually run into a problem. The whole point of having assertions is to be able to detect problems at their root instead of letting them manifest into bugs elsewhere in the software.
Thanks to conditional compilation in Flex 3, it’s now possible to
implement an assert “statement” that is mostly compiled out in the release version of your program.
Here’s my assert.as file.
package com.example.utils
{
public function assert(expression:Boolean):void
{
config::DEBUG {
if (!expression)
throw new Error("Assertion failed!");
}
}
}
As you can see, it’s very simple: If the expression is false, it throws an
“Assertion failed!” error. This part is wrapped into a conditional block: the
code is compiled into the SWF only if the config::DEBUG flag is set, not
otherwise.
In the release build of your program, you set config::DEBUG to false, which strips out the code within that conditional block.
Here’s an example of how I’m using it:
private function layoutThumbnails():void
{
var i:int = 0;
var j:int = 0;
for (; i < numChildren; i++) {
// complex calculation for layout
...
}
assert(i > j);
...
}
Does this incur a performance penalty? Yes, it does. Even though the assert
function is empty in the release build, it still seems to get called every
time. I imagine that the VM might detect it as a candidate for optimisation at
some point during the execution of the program, but it certainly isn’t doing
this during initialisation. What that means is that too many assert calls
might significantly increase your program’s startup time and thus have a
negative impact on perceived performance.
Moreover, even though the function calls might be optimised, the expressions
are still evaluated. The only way around this is to wrap the call itself into
a config::DEBUG conditional block.
I’m using this sparingly for now.
Let’s hope that the ActionScript language gets a real assertion facility in the next version.