Update 2: Faking Enums in AS3

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

Well, I couldn’t help but improve on the fake enums just a bit more (see previous article and the original one).

Because the system does involve some repetition in its pattern, it’s very likely that a copy-paste error is going to result in unwanted behavior not detected by the compiler. In fact, I did that very thing myself as I was working on an app I’m doing on the side.

Consider this code:

public class EError extends EEnum

{

{initEnum(EState);} // static ctor

public static const None :EState = new EState();

public static const CantConnect :EState = new EState();

public static const VersionMismatch :EState = new EState();

public static const Unknown :EState = new EState();

}

Whoops! We have two major classes of mistakes here.

  • The type of each constant is wrong. Hopefully the compiler will eventually catch this if you do write some type-safe code such as var err :EError = EError.None, but this isn’t guaranteed. It’s also not going to be obvious what the problem is.
  • The type sent into initEnum() is wrong. This means that EError’s constants will never get their Text fields set right. Any code that relies on this (such as for logging) will fail, not to mention the difficulty in debugging.Most likely this will get noticed right when it’s super-important: in the middle of a deep debugging session where you absolutely need to know what a certain enum is set to. Can work around it, but let’s try to avoid that happening in the first place.

Another issue I’d like to fix is to make the Text field read-only so it doesn’t get modified by accident. And we might as well rename it to a better name like Name while we’re at it.

So here’s my final solution:

import flash.utils.describeType;

public class EEnum

{

public function get Name() :String

{ return _name; }

public function toString() :String // override

{ return Name; }

protected static function initEnum(i_type :*) :void

{

var type :XML = flash.utils.describeType(i_type);

for each (var constant :XML in type.constant)

{

Page 1 of 2 | Next page