New Fun Blog – Scott Bilas

Take what you want, and leave the rest (just like your salad bar).

Archive for the ‘flex’ Category

Faking Enums in AS3

with 10 comments

[Update: the final version of my enum class is here.]

Just a little quickie. I happen to be working in Flex (which I love) and I came up with what I think is the best way to fake enums in AS3. It’s a distillation of the best I found through Google and adding my own little goodie to help debugging. It goes something like this:

class EState
{
    public var Text :String;
    {CStringUtils.InitEnumConstants(EState);} // static ctor

    public static const Initializing :EState = new EState();
    public static const Connecting   :EState = new EState();
    public static const Loading      :EState = new EState();
    public static const Ready        :EState = new EState();
}

It requires a function to set it up:

class CStringUtils
{
    public static function InitEnumConstants(inType :*) :void
    {
        var type :XML = flash.utils.describeType(inType);
        for each (var constant :XML in type.constant)
            inType[constant.@name].Text = constant.@name;
    }
}

The class “EState” above is the basic pattern I follow for all my enums. Make it a class, add a Text field, a bit of static ctor code, and then one simple line for each constant.

There are a thousand examples of how to do fake enums in AS3 on Google, but they suffer from two key flaws.

Type safety

The simplest way to fake enums in AS3 is to use an int or a string and have constants that represent each of the enum members. This isn’t type safe, not to mention is lousy for usability (code completion totally fails here). With the above method, a function receiving an EState enum can only receive an EState, which will be one of the static constants such as EState.Initializing.

Debuggability

Most of the good fake enum examples online do what I have above – a class with static const members that represent each member. The big problem is that you can’t debug these at all. If you are inspecting a class with a member var of type EState you have to also look at all the static consts of EState to compare the internal address against to find out what you’re looking at. Way better is to include in the enum constant itself its own name.

Here’s a shot of Flex’s watch window. Normally you’d only see the @46fa341, but with the “Text” string member you can expand it to see what the variable is really set to.

as3enumwatch

I saw a couple examples of this online where you’d pass in the name in the enum’s ctor, but why not automate it? That’s where the CStringUtils.InitEnumConstants comes in. For each enum class, add some static ctor code that just calls InitEnumConstants on the type. This uses reflection to initialize the names of every constant in the “enum”. Now there is exactly one place to put the name of each enum constant and it looks a lot cleaner.

Extensibility

A lot of the time you want more than just the name to be embedded in the enum constants. Perhaps a description field, or anything else that adds metadata to the constant (I wrote a bit about this earlier). No problem, just add new fields to the class, and then a ctor that receives them. Pass in the metadata initializers into the ctor as each constant is constructed.

Written by Scott

June 1st, 2008 at 10:23 am

Posted in as3, enum, flex

Switch to our mobile site