New Fun Blog – Scott Bilas

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

Faking Enums in AS3

with 11 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.

June 1st, 2008 at 10:23 am

Posted in as3,enum,flex

11 Responses to 'Faking Enums in AS3'

Subscribe to comments with RSS or TrackBack to 'Faking Enums in AS3'.

  1. [...] writings about different ways of faking Enums in ActionScript 3, I decided to do my own based on Scott’s and Barney’s [...]

  2. Maybe this could be brought to another level of automation. It’s conceivable to leave out the instantiation of the constant altogether, and leave the constant as null.

    Then, as you’re transversing through the class structure in CStringUtils.InitEnumConstants, you instantiate the constants there, along with their names.

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

    public static const Initializing :EState;
    public static const Connecting :EState;
    public static const Loading :EState;
    public static const Ready :EState;
    }

    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] = new inType();
    inType[constant.@name].Text = constant.@name;
    }
    }

    That was about as much automation as I could push it, heh. I really wanted to get rid of the static constructor and find some way to let a base Enum class handle everything, but my current idea would involve calling super(), which would need to have the constructor. Writing out the constructors is a lot more work than writing a one-liner static constructor, so i think sticking with the static is the best thus far.

    Nice work, btw. One of the most ingenious ideas I’ve ever seen.

    Cardin

    9 Dec 08 at 12:53 am

  3. Rather than post a comment reply, I figured I’d do a new post instead! :)

    http://scottbilas.com/2008/12/11/update-faking-enums-in-as3/

    Scott

    11 Dec 08 at 9:19 am

  4. Enums are my favorite community developed language feature!!!

    An Enum is a kind of variable that is not natively available in ActionScript 3.0, but can be found in other languages such as C++. An enum is a type with a restricted set of values.

    This uses Scott’s Technique!

    Here is a demo;
    http://www.blog.rivello.org/?p=621

  5. [...] Where the heck are the enums? There are some nifty ways to roll your own via reflection (looking at the XML of the class itself), but come on here, people — this [...]

  6. [...] This is hopefully the last revision I’m going to make to my fake AS3 enum class (here’s the original posting, then two updates). This is inspired by commenter Miko Korpela, who asked about an iteration [...]

  7. [...] idéa of using describeType comes from the excellent Enum pattern I love. Here is a variant of the Enum pattern I use. It’s a pity that PureMVC have strings as key and not enums. [...]

  8. [...] Further readings on AS3 enums can be found here: e.g. http://www.herrodius.com/blog/87, http://scottbilas.com/blog/faking-enums-in-as3/ or http://blog.petermolgaard.com/2008/11/02/actionscript-3-enums/ AKPC_IDS += "1149,";Popularity: [...]

  9. http://www.scripter.co.kr/186

    thank you.

    i see your posting..

    and

    i write my blog posting

    this is great idea!

    superSc

    15 Oct 11 at 6:46 am

  10. Hi, I like your ideas. I put a git-repo up with an Enum-Class by this. Maybe you’d like to have a look :)

    https://github.com/headjump/action_enum

    Dennis

    20 Jun 13 at 2:10 am

Leave a Reply