Passing data to AS classes at compile time

It's useful to be able to pass data to Flash code at compile-time rather than at runtime. So during your build process you can in some way configure the build - the obvious reason would be to turn on or off some debugging or instrumentation, but you could also configure features, pass in build numbers, set in initial languages etc. all depending on some build parameters or other.

Using a template?

The obvious way would be to in some way template the .as file you're compiling, like so:

package {
public class MyConfigClass
{
   public static const SOME_SETTING:Boolean={insert template value};
 
   public function doSomething():void
   {
      if (SOME_SETTING)
      {
          // Do it!
      }
   }
}
}

However to make that work you'd need to insert the template value during the build process, which in most cases would mean copying the source .as file, using a program to search and replace (easily automated with, say, Ant), and then compiling the resulting .as file - which would probably be in a new location. This may not sound like an issue, but it may well then be difficult to find all the files that the class depends on, especially if it embed assets. Not ideal!

The Answer - The mxmlc -define Argument

The Flex command-line compiler provides an argument called -define, which works a little bit like the /D compiler directive in C/C++ (for any C/C++ coders out there!).
It lets you declare a value as part of the compilation command-line. That value gets evaluated as the compiler builds each class, effectively doing the templating step (above) for us, without having to copy any files around.

A Simple Example - Passing Some Data

If we take our example above and alter it very slightly...

package {
public class MyConfigClass
{
   public static const SOME_SETTING:Boolean=CONFIG::someSetting;  // Actual AS3 this time
 
   public function doSomething():void
   {
      if (SOME_SETTING)
      {
          // Do it!
      }
   }
}
}

We can then at compile-time tell the compiler what value to plug into CONFIG::someSetting like so:
mxmlc MyConfigClass.as -define+=CONFIG::someSetting,true

Bingo! Compile-time configuration, inserting the word 'true' directly into the sourcecode where the compiler finds 'CONFIG::someSetting'.

The CONFIG part of the tag is an arbitrary namespace, which you can set to whatever you like; the second part (someSetting) is a variable name.

Important: If you do put an entry such as CONFIG::myString in your source code, you must pass some value to it on the command-line, or your source code just won't compile!

More Complex - Passing Different Types

The important thing to remember is that the compiler substitutes the value exactly as typed, and also that the compiler ignores the first set of quotes around the value (to allow the value to contain spaces).
So if we pass into this code:

public static const MY_STRING:String=CONFIG::myString;
public static const MY_NUMBER:Number=CONFIG::myNumber;

the following:
-define+=CONFIG::myString,"Hello!" -define+=CONFIG::myNumber,"7"

We'll get this:
public static const MY_STRING:String=Hello!; // Which won't compile!
public static const MY_NUMBER:Number=7;

So, when passing strings, put in an extra set of quotes:
-define+=CONFIG::myString,"'Hello!'" -define+=CONFIG::myNumber,"7"

which gives:
public static const MY_STRING:String='Hello!'; // Which will compile!
public static const MY_NUMBER:Number=7;

Advanced - Conditional Compilation

You can also use the define feature to include or exclude blocks of code from the final .SWF at compile time, which is a brilliant feature and highly useful when you're writing debugging code.
You use a Boolean -define value to enable or disable a block of code.
Here's an example, picking which version of a function to use at compile time:

package
{
public class MyClass
{
    CONFIG::isDebug
    public function doSomething():void
    {
        trace("This is a debug build!");
    }
 
    CONFIG::isRelease
    public function doSomething():void
    {
        trace("This is a release build!");
    }
}
}

Now this command-line will build the debug version:
mxmlc MyClass.as -define+=CONFIG::isDebug,true  -define+=CONFIG::isRelease,false

And this command-line will build the release version:
mxmlc MyClass.as -define+=CONFIG::isDebug,false -define+=CONFIG::isRelease,true

However, it's worth bearing in mind that either of these versions will cause compilation errors:
This tries to include doSomething() twice:

mxmlc MyClass.as -define+=CONFIG::isDebug,true  -define+=CONFIG::isRelease,true

And this doesn't include it at all, causing problems for anything which references it:
mxmlc MyClass.as -define+=CONFIG::isDebug,false -define+=CONFIG::isRelease,false

Conclusion

Compile-time configuration is very useful. :-) You can read all about it
on this Flex documentation page.