Alec McEachran’s latest article about constants reminded me of a trick I’ve recently learned and became a big fan of. His article expresses the pain endured by those who wish for both speed and maintainability in their AS3 apps. The solution the article doesn’t reach though is that of compile-time constants. This is truly the best of both worlds, so let’s learn about it.

Firstly, and perhaps the technique’s greatest downside, is that the constants are defined outside of the AS3 code. Instead, they are passed as arguments to MXMLC like this:

mxmlc -define=NAMESPACE::constantName,"expression"

You get to pick what NAMESPACE, constantName, and expression are. For example, here’s a way better way to access pi than Math.PI:

mxmlc -define MATH::pi,"3.14159265"

Then your AS3 code would look like this:

function circleArea(radius:Number): Number
{
	return MATH::pi * radius * radius;
}

The MATH::pi part is replaced by the constant you define on the command line, so you literally get this code compiled:

function circleArea(radius:Number): Number
{
	return 3.14159265 * radius * radius;
}

If you want to change it, you just change it in one place: the command line. More likely you are using Ant or Make or the like to manage your build, so simply change it in a properties file or the like. Now, let’s see a related math function:

function circleCircumference(radius:Number): Number
{
	return 2 * MATH::pi * radius;
}

Which yields the code:

function circleCircumference(radius:Number): Number
{
	return 2 * 3.14159265 * radius;
}

But 2 * 3.14159265 can be reduced since it too is a constant. So let’s define one:

mxmlc -define MATH::pi,"3.14159265" -define MATH::twoPi,"MATH::pi*2"

Notice how we do not even need to duplicate the constant in other compile-time constants. Now we can re-write our code like this:

function circleCircumference(radius:Number): Number
{
	return MATH::twoPi * radius;
}

Which yields:

function circleCircumference(radius:Number): Number
{
	return 6.28318531 * radius;
}

And we have now reached the optimal speed possible. We are not accessing any variable, even a local variable, we have the definition of the constant defined in one place, and we have easily readable code. It would be nicer if we could have these definitions defined in the AS3 source (like #define) rather than on the command line, but this seems like a quibble.

Well there you have it: the answer to a lot of trouble with constants. No more shall you worry about the speed of static access, that constants really just get compiled to variables, and the like. You can have true #define-style constants right now in AS3. For more on the subject, I leave you to read Adobe’s (rather hidden) documentation about this. As a bonus, it also covers conditional compilation (which I may too cover at some point) and how to use string constants. It’s only three pages, so I recommend it for everyone to read. Enjoy!