<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>New Fun Blog - Scott Bilas &#187; as3</title>
	<atom:link href="http://scottbilas.com/blog/category/as3/feed/" rel="self" type="application/rss+xml" />
	<link>http://scottbilas.com</link>
	<description>Take what you want, and leave the rest (just like your salad bar).</description>
	<lastBuildDate>Sat, 17 Sep 2011 23:47:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ultimate AS3 Fake Enums</title>
		<link>http://scottbilas.com/blog/ultimate-as3-fake-enums/</link>
		<comments>http://scottbilas.com/blog/ultimate-as3-fake-enums/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 22:00:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://scottbilas.com/?p=351</guid>
		<description><![CDATA[I just can’t leave this thing alone. 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 Mikko Korpela, who asked about an iteration ability. Well, that sounds like a fun idea! Let’s fill in some holes [...]]]></description>
			<content:encoded><![CDATA[<p>I just can’t leave this thing alone. This is hopefully the last revision I’m going to make to my fake AS3 enum class (here’s the <a href="http://scottbilas.com/blog/faking-enums-in-as3/">original posting</a>, then <a href="http://scottbilas.com/blog/update-faking-enums-in-as3/">two</a> <a href="http://scottbilas.com/2008/12/16/update-2-faking-enums-in-as3/">updates</a>). This is inspired by commenter Mikko Korpela, who <a href="http://scottbilas.com/2008/12/16/update-2-faking-enums-in-as3/#comment-304">asked about</a> an iteration ability. Well, that sounds like a fun idea! Let’s fill in some holes and bring it up to par with the enum support in C#.</p>
<p><em>Sorry it took me so long to get around to this Miko, but I’ve had my Flex work on hold for a while. But recently I did some Flash work at </em><a href="http://www.popcap.com"><em>PopCap</em></a><em> and it got me back in the mood again.</em></p>
<h2>New Enum Features</h2>
<p>Here’s my Ultimate AS3 Fake Enum class, which has the following new features:</p>
<ul>
<li>Further type safety. Only the enum can construct its own constants now, via enum constructor protection. This should prevent people using the constants incorrectly (e.g. someone is incorrectly <strong>new</strong>’ing them up instead of using <i>MyEnum.MyConstant</i>). </li>
<li>Every constant now gets a zero-based index that corresponds to the order it is created in the class. Access via the <strong>Index</strong> accessor on the constant. Useful in serialization code, for example. </li>
<li>Added a new <strong>GetConstants</strong> method that returns an array of all the constants, where each constant’s slot in the array corresponds to its <strong>Index</strong>. </li>
<li>Added a new <strong>ParseConstant</strong> method that does the reverse of <strong>toString()</strong>. Given a constant’s <strong>Name</strong>, return the constant. Case sensitivity optional and off by default for convenience. </li>
</ul>
<p>&#8230;all without any extra burden placed on the derivative class! <i>I’m always interested in solutions that keep client code as clean as possible.</i></p>
<p>I also adjusted the code to my current AS3 coding standards, which is nearly the same as Microsoft’s C# standards. <em>Note that I’d normally use <strong>Vector.&lt;Enum&gt;</strong> instead of the generic <strong>Array</strong> class, but I haven’t upgraded my Flex to the newest SDK yet.</em></p>
<h2>The Code</h2>
<p>Without further ado, here’s the new <strong>Enum.as</strong> file. Stick it in a package if you wish, and drop it wherever you like. No system setup is required to make it work.</p>
<pre class="brush: as3;">
package
{
	import flash.utils.*;

	public /*abstract*/ class Enum
	{
		public function get Name()  :String { return _name; }
		public function get Index() :int    { return _index; }

		public /*override*/ function toString() :String { return Name; }

		public static function GetConstants(i_type :Class) :Array
		{
			var constants :EnumConstants = _enumDb[getQualifiedClassName(i_type)];
			if (constants == null)
				return null;

			// return a copy to prevent caller modifications
			return constants.ByIndex.slice();
		}

		public static function ParseConstant(
				i_type			:Class,
				i_constantName  :String,
				i_caseSensitive :Boolean = false) :Enum
		{
			var constants :EnumConstants = _enumDb[getQualifiedClassName(i_type)];
			if (constants == null)
				return null;

			var constant :Enum = constants.ByName[i_constantName.toLowerCase()];
			if (i_caseSensitive &amp;&amp; (constant != null) &amp;&amp; (i_constantName != constant.Name))
				return null;

			return constant;
		}

		/*-----------------------------------------------------------------*/

		/*protected*/ function Enum()
		{
			var typeName :String = getQualifiedClassName(this);

			// discourage people new'ing up constants on their own instead
			// of using the class constants
			if (_enumDb[typeName] != null)
			{
				throw new Error(
					&quot;Enum constants can only be constructed as static consts &quot; +
					&quot;in their own enum class &quot; + &quot;(bad type='&quot; + typeName + &quot;')&quot;);
			}

			// if opening up a new type, alloc an array for its constants
			var constants :Array = _pendingDb[typeName];
			if (constants == null)
				_pendingDb[typeName] = constants = [];

			// record
			_index = constants.length;
			constants.push(this);
		}

		protected static function initEnum(i_type :Class) :void
		{
			var typeName :String = getQualifiedClassName(i_type);

			// can't call initEnum twice on same type (likely copy-paste bug)
			if (_enumDb[typeName] != null)
			{
				throw new Error(
					&quot;Can't initialize enum twice (type='&quot; + typeName + &quot;')&quot;);
			}

			// no constant is technically ok, but it's probably a copy-paste bug
			var constants :Array = _pendingDb[typeName];
			if (constants == null)
			{
				throw new Error(
					&quot;Can't have an enum without any constants (type='&quot; +
					typeName + &quot;')&quot;);
			}

			// process constants
			var type :XML = flash.utils.describeType(i_type);
			for each (var constant :XML in type.constant)
			{
				// this will fail to coerce if the type isn't inherited from Enum
				var enumConstant :Enum = i_type[constant.@name];

				// if the types don't match then probably have a copy-paste error.
				// this is really common so it's good to catch it here.
				var enumConstantType :* = Object(enumConstant).constructor;
				if (enumConstantType != i_type)
				{
					throw new Error(
						&quot;Constant type '&quot; + enumConstantType + &quot;' &quot; +
						&quot;does not match its enum class '&quot; + i_type + &quot;'&quot;);
				}

				enumConstant._name = constant.@name;
			}

			// now seal it
			_pendingDb[typeName] = null;
			_enumDb[typeName] = new EnumConstants(constants);
		}

		private var _name :String = null;
		private var _index :int = -1;

		private static var _pendingDb :Object = {};	// typename -&gt; [constants]
		private static var _enumDb	  :Object = {};	// typename -&gt; EnumConstants
	}
}

// private support class
class EnumConstants
{
	public function EnumConstants(i_byIndex :Array)
	{
		ByIndex = i_byIndex;

		for (var i :int = 0; i &lt; ByIndex.length; ++i)
		{
			var enumConstant :Enum = ByIndex[i];
			ByName[enumConstant.Name.toLowerCase()] = enumConstant;
		}
	}

	public var ByIndex :Array;
	public var ByName :Object = {};
}
</pre>
<h2>The Samples</h2>
<p>Here are a couple sample enums and some code to demonstrate the features.</p>
<h3>Simple Enum: State</h3>
<p>This is the simplest usage of the <strong>Enum</strong> class. All you have to do to make a fake enum is:</p>
<ol>
<li>Create a class that extends the <strong>Enum</strong> class. Tag it as <strong>final</strong> too so nobody inherits it (that would be weird).</li>
<li>Put some static init code in there that just calls <strong>initEnum(MyTypeName)</strong>. This will get run on demand, on the first usage of the enum by other code. It sets up the necessary lookup tables and attaches a Name and Index to each enum constant.</li>
<li>Create a <strong>public static const</strong> for each enum constant you want, following the pattern in the sample.</li>
</ol>
<p>Here&#8217;s the sample enum. Note that it includes a bug on purpose! (It&#8217;s clearly marked.)</p>
<pre class="brush: as3;">
package
{
	public final class State extends Enum
	{
		{initEnum(State);} // static ctor

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

		// illegal; this will fail at runtime
		public static const Test		 :OtherEnum = new OtherEnum();
	}
}
</pre>
<p>And some test code to walk through the features…</p>
<pre class="brush: as3;">
for each (var state :State in Enum.GetConstants(State))
{
	trace(state.Index + &quot;: &quot; + state.Name);
}

trace(&quot;connecting (no case): &quot; + Enum.ParseConstant(State, &quot;connecting&quot;));
trace(&quot;connecting (with case): &quot; + Enum.ParseConstant(State, &quot;connecting&quot;, true));

// illegal; gets a runtime exception
var someEnum :State = new State();
</pre>
<p>Which produces the following output:</p>
<pre class="brush: plain;">
0: Initializing
1: Connecting
2: Loading
3: Ready
connecting (no case): Connecting
connecting (with case): null
Error: Enum constants can only be constructed as static consts in their own enum class (bad type='State')
 ...
</pre>
<h3>Advanced Enum: NetError</h3>
<p>Let’s look at a more advanced sample, which I’m calling an “attributed” enum. Let’s say we have a NetError enum with constants for different types of failures on a network request. We want to be able to show a more user-friendly error, and perhaps classify it as a fatal error or not. We could have a table that associates extended attributes for enum constants with those constants, but why not just attach them to the constants directly?</p>
<p>In .NET I’d do this with attributes. Now, AS3 doesn’t support attributes like we need, so we’ll have to fake it. Given that we already have a fake enum constant, which is really an object underneath, we can attach whatever we like to it!</p>
<p>Take a look at the sample enum.</p>
<pre class="brush: as3;">
package
{
	public final class NetError extends Enum
	{
		{ initEnum(NetError); } // static ctor

	// Constants.

		public static const None			:NetError = new NetError(false, &quot;no error&quot;);
		public static const CantConnect		:NetError = new NetError(false, &quot;can't connect to the server, must be down?&quot;);
		public static const VersionMismatch	:NetError = new NetError(true,  &quot;protocol versions different&quot;);
		public static const Unknown			:NetError = new NetError(true,  &quot;unexpected error type&quot;);

	// Constant attributes.

		public function get IsFatal()	  :Boolean	{ return _isFatal; }
		public function get Description() :String	{ return _description; }		

	// Constant query.

		public static function GetConstants() :Array
			{ return Enum.GetConstants(NetError); }
		public static function ParseConstant(i_constantName :String, i_caseSensitive :Boolean = false) :NetError
			{ return NetError(Enum.ParseConstant(NetError, i_constantName, i_caseSensitive)); }

	// Private.

		/*private*/ function NetError(i_isFatal :Boolean, i_description :String)
			{ _isFatal = i_isFatal; _description = i_description; }
		private var _isFatal	 :Boolean;
		private var _description :String;
	}
}
</pre>
<p>Given a constant, perhaps returned from a function as an error code, or thrown as part of an exception, we can ask it for its friendlier name by accessing its <strong>Description</strong> member.</p>
<p>Also in this class note the helper functions <strong>GetConstants</strong> and <strong>ParseConstant</strong> that wrap the <strong>Enum</strong> class versions, automatically passing in the local type. This isn’t necessary, but is a nice convenience. It is a bit more code to copy-paste around when adding new enums, though. If only AS3 supported templates, we could have a <strong>TEnum</strong> base that does all this for us. Ah well.</p>
<p>Here is some test code to play with the features</p>
<pre class="brush: as3;">
for each (var netError :NetError in NetError.GetConstants())
{
	trace(
		netError.Index + &quot;: &quot; + netError.Name +
		&quot; (&quot; + netError.Description + &quot;) &quot; +
		(netError.IsFatal ? &quot;[FATAL]&quot; : &quot;&quot;));
}
</pre>
<p>Which produces the following output:</p>
<pre class="brush: plain;">
0: None (no error)
1: CantConnect (can't connect to the server, must be down?)
2: VersionMismatch (protocol versions different) [FATAL]
3: Unknown (unexpected error type) [FATAL]
</pre>
<h2>Future?</h2>
<p>I hope this is the last word on fake enums in Actionscript. Not because I don’t think anyone else can improve on it, but because I’m hoping that the next version of the language will have native support for enums. Then we can put all this fakery behind us and get on with our lives.</p>
<p>The enum posts are among the top hitters on my blog, and they are popular topics elsewhere on the web. I’m hoping that Adobe will strongly consider native enum support in their next Flash player.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/ultimate-as3-fake-enums/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Update 2: Faking Enums in AS3</title>
		<link>http://scottbilas.com/blog/update-2-faking-enums-in-as3/</link>
		<comments>http://scottbilas.com/blog/update-2-faking-enums-in-as3/#comments</comments>
		<pubDate>Wed, 17 Dec 2008 02:01:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://scottbilas.wordpress.com/2008/12/16/update-2-faking-enums-in-as3/</guid>
		<description><![CDATA[[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 [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>[Update: the final version of my enum class is <a href="../ultimate-as3-fake-enums/">here</a>.]</strong></em></p>
<p><em><strong> </strong></em>Well, I couldn’t help but improve on the fake enums just a bit more (see <a href="http://scottbilas.com/blog/update-faking-enums-in-as3/" target="_blank">previous article</a> and the <a href="http://scottbilas.com/blog/faking-enums-in-as3/" target="_blank">original</a> one).</p>
<p>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.</p>
<p>Consider this code:</p>
<pre class="code"><span style="color: blue;">public class </span><span style="color: #010001;">EError </span><span style="color: blue;">extends </span><span style="color: #010001;">EEnum
</span>{
    {<span style="color: #010001;">initEnum</span>(<span style="color: #010001;">EState</span>);} <span style="color: green;">// static ctor

    </span><span style="color: blue;">public static const </span><span style="color: #010001;">None            </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();<span style="color: green;">
    </span><span style="color: blue;">public static const </span><span style="color: #010001;">CantConnect     </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();<span style="color: green;">
    </span><span style="color: blue;">public static const </span><span style="color: #010001;">VersionMismatch </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();<span style="color: green;">
    </span><span style="color: blue;">public static const </span><span style="color: #010001;">Unknown         </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();<span style="color: green;">
</span>}</pre>
<p>Whoops! We have two major classes of mistakes here.</p>
<ul>
<li><em>The type of each constant is wrong. </em><em> </em>Hopefully the compiler will eventually catch this if you do write some type-safe code such as <em>var err :EError = EError.None</em>, but this isn’t guaranteed. It’s also not going to be obvious what the problem is.</li>
<li><em>The type sent into initEnum() is wrong. </em><em> </em>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.</li>
</ul>
<p>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.</p>
<p>So here’s my final solution:</p>
<pre class="code"><span style="color: blue;">import </span><span style="color: #010001;">flash</span>.<span style="color: #010001;">utils</span>.<span style="color: #010001;">describeType</span>;

<span style="color: blue;">public class </span><span style="color: #010001;">EEnum
</span>{
    <span style="color: blue;">public function get </span><span style="color: #010001;">Name</span>() :<span style="color: #010001;">String
        </span>{ <span style="color: blue;">return </span><span style="color: #010001;">_name</span>; }

    <span style="color: blue;">public function </span><span style="color: #010001;">toString</span>() :<span style="color: #010001;">String </span><span style="color: green;">// override
        </span>{ <span style="color: blue;">return </span><span style="color: #010001;">Name</span>; }

    <span style="color: blue;">protected static function </span><span style="color: #010001;">initEnum</span>(<span style="color: #010001;">i_type </span>:*) :<span style="color: blue;">void
    </span>{
        <span style="color: blue;">var </span><span style="color: #010001;">type </span>:<span style="color: #010001;">XML </span>= <span style="color: #010001;">flash</span>.<span style="color: #010001;">utils</span>.<span style="color: #010001;">describeType</span>(<span style="color: #010001;">i_type</span>);
        <span style="color: blue;">for </span><span style="color: #010001;">each </span>(<span style="color: blue;">var </span><span style="color: #010001;">constant </span>:<span style="color: #010001;">XML </span><span style="color: blue;">in </span><span style="color: #010001;">type</span>.<span style="color: #010001;">constant</span>)
        {
            <span style="color: blue;">var </span><span style="color: #010001;">enumConstant </span>:<span style="color: #010001;">EEnum </span>= <span style="color: #010001;">i_type</span>[<span style="color: #010001;">constant</span>.<span style="color: #010001;">@name</span>];

            <span style="color: green;">// if 'text' is already initialized, then we're probably
            // calling initEnum() on the same type twice by accident,
            // likely a copy-paste bonehead mistake.
            </span><span style="color: blue;">if </span>(<span style="color: #010001;">enumConstant</span>.<span style="color: #010001;">Name </span>!= <span style="color: blue;">null</span>)
            {
                <span style="color: blue;">throw new </span><span style="color: #010001;">Error</span>(<span style="color: #a31515;">"Can't initialize '" </span>+ <span style="color: #010001;">i_type </span>+ <span style="color: #a31515;">"' twice"</span>);
            }

            <span style="color: green;">// if the types don't match then probably have another
            // copy-paste error.
            </span><span style="color: blue;">var </span><span style="color: #010001;">enumConstantObj </span>:* = <span style="color: #010001;">enumConstant</span>;
            <span style="color: blue;">if </span>(<span style="color: #010001;">enumConstantObj</span>.<span style="color: #010001;">constructor </span>!= <span style="color: #010001;">i_type</span>)
            {
                <span style="color: blue;">throw new </span><span style="color: #010001;">Error</span>(
                    <span style="color: #a31515;">"Constant type '" </span>+ <span style="color: #010001;">enumConstantObj</span>.<span style="color: #010001;">constructor </span>+ <span style="color: #a31515;">"' " </span>+
                    <span style="color: #a31515;">"does not match its enum class '" </span>+ <span style="color: #010001;">i_type </span>+ <span style="color: #a31515;">"'"</span>);
            }

            <span style="color: #010001;">enumConstant</span>.<span style="color: #010001;">_name </span>= <span style="color: #010001;">constant</span>.<span style="color: #010001;">@name</span>;
        }
    }

    <span style="color: blue;">private var </span><span style="color: #010001;">_name </span>:<span style="color: #010001;">String </span>= <span style="color: blue;">null</span>;
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>This has the following fixes:</p>
<ul>
<li>Changed Text to _name, and made it private so only initEnum() will mess with it.</li>
<li>Added an accessor for _name called Name for convenience, and threw in a toString() to be more ActionScripty.</li>
<li>Added double-init testing. I put this on the constant _name init but could have also had a bool _initted attached to the EEnum. Same result either way, but I think this is a little bit safer because it avoids the (admittedly unlikely) scenario of an enum pulling constants from another. It’s certainly not any harder to understand.</li>
<li>Added a test to make sure that each constant initted in the enum is actually of the type requested.</li>
</ul>
<p>There. Now I’ve done this simple bit of code to death and we can move on. <img src='http://scottbilas.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/update-2-faking-enums-in-as3/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Update: Faking Enums in AS3</title>
		<link>http://scottbilas.com/blog/update-faking-enums-in-as3/</link>
		<comments>http://scottbilas.com/blog/update-faking-enums-in-as3/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 16:00:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://scottbilas.wordpress.com/2008/12/11/update-faking-enums-in-as3/</guid>
		<description><![CDATA[[Update: the final version of my enum class is here.]
Cardin posted a comment (thanks!) with an update to Faking Enums in AS3, and rather than post a comment reply, I figured I’d do a new post instead. Then I can get syntax highlighting.  
I did some tests in Flex and unfortunately, this simplification won&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>[Update: the final version of my enum class is <a href="../ultimate-as3-fake-enums/">here</a>.]</strong></em></p>
<p><a href="http://cardinal4.co.cc/" target="_blank">Cardin</a> posted a <a href="http://scottbilas.com/blog/faking-enums-in-as3/" target="_blank">comment</a> (thanks!) with an update to <a href="http://scottbilas.com/blog/faking-enums-in-as3/" target="_blank">Faking Enums in AS3</a>, and rather than post a comment reply, I figured I’d do a new post instead. Then I can get syntax highlighting. <img src='http://scottbilas.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I did some tests in Flex and unfortunately, this simplification won&#8217;t work. A couple problems arise.</p>
<p>First, if you don&#8217;t init those constants in EState and just leave them unassigned, then the Flex compiler gives a warning for each with a little hazard icon next to each constant. Not is this annoying, for me it’s a deal-breaker. I insist on having warning-clean projects. Warnings are so useful for catching bugs, that I always set them to the max. Also, if an option is available on the compiler I’m using to turn warnings into errors, then I always set it to make sure those warnings get fixed. We do the same at my work. Catches lots of great stuff.</p>
<p>So let&#8217;s just assign each of those constants to null. It’s not ideal but it is still a bit simpler than &#8216;new EState()&#8217;. Now we run into the second problem. The VM refuses to let you modify those constants. This was actually a pleasant surprise for me. I’m so accustomed to older versions of ActionScript letting you do whatever sloppy stuff you want. Powerful but dangerous in the long run. The new compiler throws an exception:</p>
<blockquote><p><span style="color: #ae0000;">ReferenceError: Error #1074: Lectura no permitida de la propiedad Ready de sólo lectura en class EState.<br />
at EEnum$/initEnum()[C:\Users\sbilas\Proj\tt\main\test-flex\src\EEnum.as:14]</span></p></blockquote>
<p>Sorry it’s in español, but that’s how I have my machine configured (me gusta practicar). Roughly translated it says that writing isn’t permitted from the read-only property. Well actually it says that reading isn’t permitted but I’m pretty sure that’s a translation bug (should be “escritura”). I tested with a trace statement and reading works just fine.</p>
<p>Anyway, the exception happens when trying to assign in that “new inType()”. So the “= new EState() can&#8217;t be left out for each constant, unfortunately, as far as I can tell. We could remove the &#8216;const&#8217; but that&#8217;s starting to sacrifice safety for a small amount of programmer convenience. The enum is going to be used far more often than it will be written, so we&#8217;ll leave the const in there.</p>
<p>However, there is one tiny improvement I was able to make, and it looks like this:</p>
<pre class="code"><span style="color: blue;">import </span><span style="color: #010001;">flash</span>.<span style="color: #010001;">utils</span>.<span style="color: #010001;">describeType</span>;

<span style="color: blue;">public class </span><span style="color: #010001;">EEnum
</span>{
    <span style="color: blue;">public var </span><span style="color: #010001;">Text </span>:<span style="color: #010001;">String</span>;

    <span style="color: blue;">protected static function </span><span style="color: #010001;">initEnum</span>(<span style="color: #010001;">i_type </span>:*) :<span style="color: blue;">void
    </span>{
        <span style="color: blue;">var </span><span style="color: #010001;">type </span>:<span style="color: #010001;">XML </span>= <span style="color: #010001;">flash</span>.<span style="color: #010001;">utils</span>.<span style="color: #010001;">describeType</span>(<span style="color: #010001;">i_type</span>);
        <span style="color: blue;">for </span><span style="color: #010001;">each </span>(<span style="color: blue;">var </span><span style="color: #010001;">constant </span>:<span style="color: #010001;">XML </span><span style="color: blue;">in </span><span style="color: #010001;">type</span>.<span style="color: #010001;">constant</span>)
        {
            <span style="color: #010001;">i_type</span>[<span style="color: #010001;">constant</span>.<span style="color: #010001;">@name</span>].<span style="color: #010001;">Text </span>= <span style="color: #010001;">constant</span>.<span style="color: #010001;">@name</span>;
        }
    }
}

<span style="color: blue;">public class </span><span style="color: #010001;">EState </span><span style="color: blue;">extends </span><span style="color: #010001;">EEnum
</span>{
    <span style="color: green;">// static ctor
    </span>{<span style="color: #010001;">initEnum</span>(<span style="color: #010001;">EState</span>);}

    <span style="color: blue;">public static const </span><span style="color: #010001;">Initializing </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();
    <span style="color: blue;">public static const </span><span style="color: #010001;">Connecting   </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();
    <span style="color: blue;">public static const </span><span style="color: #010001;">Loading      </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();
    <span style="color: blue;">public static const </span><span style="color: #010001;">Ready        </span>:<span style="color: #010001;">EState </span>= <span style="color: blue;">new </span><span style="color: #010001;">EState</span>();
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>So, we have a base class to extend that holds the Text field, and we might as well move the constant init code into the base as well instead of a general utility class. It&#8217;s probably only ever going to be used in this way anyway.</p>
<p>Overall this is a bit simpler now. This reduces the requirements for an enum to three fairly minimal things:</p>
<ul>
<li>Extend EEnum.</li>
<li>Call initEnum(EnumType) in a static ctor.</li>
<li>Set all enum &#8220;constants&#8221; as public static consts assigned to a new EnumType().</li>
</ul>
<p>If you can get it any smaller than this, then please post a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/update-faking-enums-in-as3/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Faking Enums in AS3</title>
		<link>http://scottbilas.com/blog/faking-enums-in-as3/</link>
		<comments>http://scottbilas.com/blog/faking-enums-in-as3/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 18:23:06 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://scottbilas.wordpress.com/2008/06/01/faking-enums-in-as3/</guid>
		<description><![CDATA[[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&#8217;s a distillation of the best I found through Google and adding my own little [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>[Update: the final version of my enum class is <a href="../ultimate-as3-fake-enums/">here</a>.]</strong></em></p>
<p>Just a little quickie. I happen to be working in Flex (which I <em>love</em>) and I came up with what I think is the best way to fake enums in AS3. It&#8217;s a distillation of the best I found through Google and adding my own little goodie to help debugging. It goes something like this:</p>
<pre><span style="color: blue;">class </span><span style="color: #2b91af;">EState
</span>{
    <span style="color: blue;">public </span><span style="background: #f0f2ee; color: #020002;">var</span> <span style="background: #f0f2ee; color: #020002;">Text</span> :<span style="background: #f0f2ee; color: #020002;">String</span>;
    {<span style="background: #f0f2ee; color: #020002;">CStringUtils</span>.<span style="background: #f0f2ee; color: #020002;">InitEnumConstants</span>(<span style="background: #f0f2ee; color: #020002;">EState</span>);} <span style="color: green;">// static ctor

    </span><span style="color: blue;">public static const </span><span style="background: #f0f2ee; color: #020002;">Initializing</span> :<span style="background: #f0f2ee; color: #020002;">EState</span> = <span style="color: blue;">new </span><span style="background: #f0f2ee; color: #020002;">EState</span>();
    <span style="color: blue;">public static const </span><span style="background: #f0f2ee; color: #020002;">Connecting</span>   :<span style="background: #f0f2ee; color: #020002;">EState</span> = <span style="color: blue;">new </span><span style="background: #f0f2ee; color: #020002;">EState</span>();
    <span style="color: blue;">public static const </span><span style="background: #f0f2ee; color: #020002;">Loading</span>      :<span style="background: #f0f2ee; color: #020002;">EState</span> = <span style="color: blue;">new </span><span style="background: #f0f2ee; color: #020002;">EState</span>();
    <span style="color: blue;">public static const </span><span style="background: #f0f2ee; color: #020002;">Ready</span>        :<span style="background: #f0f2ee; color: #020002;">EState</span> = <span style="color: blue;">new </span><span style="background: #f0f2ee; color: #020002;">EState</span>();
}</pre>
<p>It requires a function to set it up:</p>
<pre><span style="color: blue;">class </span><span style="background: #f0f2ee; color: #020002;">CStringUtils
</span>{
    <span style="color: blue;">public static </span><span style="background: #f0f2ee; color: #020002;">function</span> <span style="background: #f0f2ee; color: #020002;">InitEnumConstants</span>(<span style="background: #f0f2ee; color: #020002;">inType</span> :*) :<span style="color: blue;">void
    </span>{
        <span style="background: #f0f2ee; color: #020002;">var</span> <span style="background: #f0f2ee; color: #020002;">type</span> :<span style="background: #f0f2ee; color: #020002;">XML</span> = <span style="background: #f0f2ee; color: #020002;">flash</span>.<span style="background: #f0f2ee; color: #020002;">utils</span>.<span style="background: #f0f2ee; color: #020002;">describeType</span>(<span style="background: #f0f2ee; color: #020002;">inType</span>);
        <span style="color: blue;">for </span><span style="background: #f0f2ee; color: #020002;">each</span> (<span style="background: #f0f2ee; color: #020002;">var</span> <span style="background: #f0f2ee; color: #020002;">constant</span> :<span style="background: #f0f2ee; color: #020002;">XML</span> <span style="color: blue;">in </span><span style="background: #f0f2ee; color: #020002;">type</span>.<span style="background: #f0f2ee; color: #020002;">constant</span>)
            <span style="background: #f0f2ee; color: #020002;">inType</span>[<span style="background: #f0f2ee; color: #020002;">constant</span>.<span style="background: #f0f2ee; color: #020002;">@name</span>].<span style="background: #f0f2ee; color: #020002;">Text</span> = <span style="background: #f0f2ee; color: #020002;">constant</span>.<span style="background: #f0f2ee; color: #020002;">@name</span>;
    }
}</pre>
<p>The class &#8220;EState&#8221; 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.</p>
<p>There are a thousand examples of how to do fake enums in AS3 on Google, but they suffer from two key flaws.</p>
<h2>Type safety</h2>
<p>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&#8217;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 <em>EState.Initializing</em>.</p>
<h2>Debuggability</h2>
<p>Most of the good fake enum examples online do what I have above &#8211; a class with static const members that represent each member. The big problem is that you can&#8217;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&#8217;re looking at. Way better is to include in the enum constant itself its own name.</p>
<p>Here&#8217;s a shot of Flex&#8217;s watch window. Normally you&#8217;d only see the @46fa341, but with the &#8220;Text&#8221; string member you can expand it to see what the variable is really set to.</p>
<p><a href="http://scottbilas.com/wp-content/uploads/2008/06/as3enumwatch.png"><img style="border: 0;" src="http://scottbilas.com/wp-content/uploads/2008/06/as3enumwatch-thumb.png" border="0" alt="as3enumwatch" width="423" height="138" /></a></p>
<p>I saw a couple examples of this online where you&#8217;d pass in the name in the enum&#8217;s ctor, but why not automate it? That&#8217;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 &#8220;enum&#8221;. Now there is exactly one place to put the name of each enum constant and it looks a lot cleaner.</p>
<h2>Extensibility</h2>
<p>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 <a href="http://scottbilas.com/blog/adding-attributes-to-enums-background/">earlier</a>). 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.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbilas.com/blog/faking-enums-in-as3/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

