<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7206051964260112891</id><updated>2011-11-27T18:11:46.922-08:00</updated><category term='actionscript events clone'/><category term='actionscript trace firebug console debug log firefox'/><category term='inheritance super variables'/><category term='refactoring'/><category term='actionscript oop variables classes passthrough'/><category term='interface actionscript oop'/><category term='actionscript testing fla Flash ide'/><category term='programming coding managers clients planning'/><category term='division divided zero NaN Infinity browsers math firefox internetexplorer flash player flashplayer ie'/><category term='null debugging escape unescape conditional'/><category term='actionscript scale'/><category term='objective-c'/><category term='jquery'/><category term='constructor interface'/><category term='bezier corner round rounding rounded actionscript shape shapes'/><category term='actionscript 3.0'/><category term='regexp filename actionscript'/><category term='actionscript text color regexp regularexpression textfield'/><category term='parameter actionscript order storytelling instances'/><category term='actionscript cdn'/><category term='actionscript factory factories oop conditional conditionals switch case if'/><category term='coding'/><category term='getters setters oop actionscript air app'/><category term='rss opml actionscript vienna blogs feeds'/><category term='actionscript'/><category term='server cache browser actioncript'/><category term='mac osx apps applications'/><category term='actionscript bugs'/><category term='refactoring actionscript'/><title type='text'>grumblecode</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>41</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-1065822809377501014</id><published>2010-03-04T07:35:00.000-08:00</published><updated>2010-03-04T07:41:44.964-08:00</updated><title type='text'>closures in actionscript</title><content type='html'>From time to time, I've read that you can use closures in Actionscript, but I've never found a use for them until now. Before I explain that use, let me go over what closures are and how they work.&lt;br /&gt;&lt;br /&gt;Normally, local variables die after functions are through running:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function someFunction() : void&lt;br /&gt;{&lt;br /&gt;    var myFriend : String = "Fred";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;someFunction();&lt;br /&gt;trace( myFriend ); //1120: Access of undefined property myFriend.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But things get wacky when functions return other functions:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function functionMaker() : Function&lt;br /&gt;{&lt;br /&gt;    return function() : void { trace ( "I am a new function!" ) }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above example, I haven't used any variables. I'll add one shortly. For now, just note that functionMaker's return type is Function and that it, in fact, does return a function. The function it returns in anonymous. That is, it doesn't have a name. We can access it this way:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var aNewFunction : Function = functionMaker();&lt;br /&gt;aNewFunction(); //I am a new function!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;functionMaker returns a new (anonymous) function, which we stored in a variable called aNewFunction. We then called the function stored in aNewFunction by following the variable's name with the call operator: ().&lt;br /&gt;&lt;br /&gt;You can shorten the above to...&lt;br /&gt;&lt;br /&gt;functionMaker()();&lt;br /&gt;&lt;br /&gt;That looks odd, but it works. The first call operator calls functionMaker; the second class the function that functionMaker returns.&lt;br /&gt;&lt;br /&gt;Let's take another look at the guts of functionMaker:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function functionMaker() : Function&lt;br /&gt;{&lt;br /&gt;    return function() : void { trace ( "I am a new function!" ) }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;From now on, in the case of functions that return other functions, I'm going to call the main function the outer function and the returned function the inner function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//outer function&lt;br /&gt;function functionMaker() : Function&lt;br /&gt;{&lt;br /&gt;            //inner function&lt;br /&gt;    return function() : void { trace ( "I am a new function!" ) }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What happens if we create a local variable in the outer function and try to reference it from the main body of our code?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function functionMaker() : Function&lt;br /&gt;{&lt;br /&gt;    var food : String = "cheese"?&lt;br /&gt;   &lt;br /&gt;    return function() : void { trace ( "I am a new function!" ) }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;functionMaker();&lt;br /&gt;trace( food ); //1120: Access of undefined property food.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;No surprise. food is a local variable to functionMaker. We can't access it from outside the function. However, what if we try to access it from within the inner function?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function functionMaker() : Function&lt;br /&gt;{&lt;br /&gt;    var food : String = "cheese"?&lt;br /&gt;   &lt;br /&gt;    return function() : void { trace ( "I am a new function, and I love " + food + "!" ) }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var aNewFunction : Function = functionMaker();&lt;br /&gt;aNewFunction(); //I am a new function, and I love cheese!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Take a moment to think about what just happened. When we ran the inner function, it spit out the word "cheese" as part of its output, even though that word wasn't stored inside it. It got that word by referencing the outer function's variable. So inner functions have references to the variables in their parent functions.&lt;br /&gt;&lt;br /&gt;Now take a closer look at these lines:&lt;br /&gt;&lt;br /&gt;1. var aNewFunction : Function = functionMaker();&lt;br /&gt;2. aNewFunction(); //I am a new function, and I love cheese!&lt;br /&gt;&lt;br /&gt;functionMaker, the function that contains the value "cheese" finishes running on line one, so under normal circumstances, cheese should be dead by line two. But it's not. And that, kids, is a closure: &lt;em&gt;inner functions have access to the variables in their parent, outer functions even after those outer functions have stopped running!&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Not only can they access those variables, they can alter them!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function functionMaker() : Function&lt;br /&gt;{&lt;br /&gt;    var food : String = "cheese"?&lt;br /&gt;   &lt;br /&gt;    return function() : void { food += " crackers"; trace( "I am a new function, and I love " + food + "!" ) }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var aNewFunction : Function = functionMaker();&lt;br /&gt;aNewFunction(); //I am a new function, and I love cheese crackers!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There's one last key aspect of closers I haven't explained: From the inner-function's point-of-view, the variable is static. That is, it keeps its value even after the inner function is done running! That means that each time you call the inner function, it can access the last value stores in the variable.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function counterMaker() : Function&lt;br /&gt;{&lt;br /&gt;    var count : int = 0;&lt;br /&gt;   &lt;br /&gt;    return function() : void { trace( count ++ ) }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var aNewCounter = counterMaker();&lt;br /&gt;aNewCounter(); //0&lt;br /&gt;aNewCounter(); //1&lt;br /&gt;aNewCounter(); //2&lt;br /&gt;aNewCounter(); //3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Compare this with a stand-alone version of the inner function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function counter() : void&lt;br /&gt;{&lt;br /&gt;    var count : int = 0;&lt;br /&gt;    trace( count++ );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;counter(); //0&lt;br /&gt;counter(); //0&lt;br /&gt;counter(); //0&lt;br /&gt;counter(); //0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the stand-alone version, the variable counter gets reset to zero each time the function is called. It gets incremented in the trace, but by then it's too late. The function is over and its local variable dies. We can use closures to add static variables to functions!&lt;br /&gt;&lt;br /&gt;As I said at the top of this article, I had read about closers for years, but I didn't see how they were useful in Actionsctipt, which is an object-oriented language. As such, if I wanted a counter with a static variable, I would make and use one like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Counter&lt;br /&gt;{&lt;br /&gt;    private var _count : int = 0;&lt;br /&gt;   &lt;br /&gt;    public function next() : { trace( _count++ ) }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var counter : Counter = new Counter();&lt;br /&gt;counter.next(); //0&lt;br /&gt;counter.next(); //1&lt;br /&gt;counter.next(); //2&lt;br /&gt;counter.next(); //3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So what made me suddenly want to use a closure? Well, I was trying to do something very specific involving regular expressions. I started with this text:&lt;br /&gt;&lt;br /&gt;Photo is of a sunset.&lt;br /&gt;Photo is of my sister.&lt;br /&gt;Photo is of a horse.&lt;br /&gt;Photo is of a birthday party.&lt;br /&gt;... [many other similar lines]&lt;br /&gt;Photo is of a calm lake near the city.&lt;br /&gt;&lt;br /&gt;From that, I wanted to output...&lt;br /&gt;&lt;br /&gt;Photo1 is of a sunset.&lt;br /&gt;Photo2 is of my sister.&lt;br /&gt;Photo3 is of a horse.&lt;br /&gt;Photo4 is of a birthday party.&lt;br /&gt;... [many other similar lines]&lt;br /&gt;Photo[n] is of a calm lake near the city.&lt;br /&gt;&lt;br /&gt;...with each new "Photo" getting an incremented number appended to it.&lt;br /&gt;&lt;br /&gt;To start out with a simpler example, let's say that I didn't care about the numbers incrementing. I just want a random number appended to the end of each "Photo" (Photo2, Photo9, Photo3, etc.).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var text : String = "";&lt;br /&gt;text += "Photo is of a sunset.";&lt;br /&gt;text += "Photo is of my sister.";&lt;br /&gt;text += "Photo is of a horse.";&lt;br /&gt;text += "Photo is of a birthday party.";&lt;br /&gt;text += "Photo is of a calm lake near the city.";&lt;br /&gt;&lt;br /&gt;var regExp : RegExp = new RegExp( "Photo", "g" );&lt;br /&gt;&lt;br /&gt;text = text.replace( regExp, String( Math.round( Math.random() * 10 ) );&lt;br /&gt;trace( text );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That doesn't get me exactly what I want. It doesn't append a random number onto the end of each "Photo". Instead, it replaces each "Photo" with a random number:&lt;br /&gt;&lt;br /&gt;6 is of a sunset.&lt;br /&gt;0 is of my sister.&lt;br /&gt;10 is of a horse.&lt;br /&gt;6 is of a birthday party.&lt;br /&gt;3 is of a calm lake near the city.&lt;br /&gt;&lt;br /&gt;I could prepend the original string "Photo" onto the random number ...&lt;br /&gt;&lt;br /&gt;text = text.replace( regExp, "Photo" + Math.round( Math.random() * 10 );&lt;br /&gt;&lt;br /&gt;... but that second parameter is starting to get long, ugly and unreadable. Luckily, the String.replace() method accepts a function as its second parameter:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function appendRandomNumber() : String&lt;br /&gt;{&lt;br /&gt;    return arguments[ 0 ] + Math.round( Math.random() * 10 );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var regExp : RegExp = new RegExp( "Photo", "g" );&lt;br /&gt;&lt;br /&gt;text = text.replace( regExp, appendRandomNumber );&lt;br /&gt;trace( text );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What happens here is that replace calls the appendRandomNumber method, handing it an array, which the function receives in a variable called arguments. If you want to know everything that's stored in the array, look up String.replace() in help. All we care about here is arguments[0], which contains whatever the regular expression matched: in this case, the word "Photo." The function returns that plus a random number:&lt;br /&gt;&lt;br /&gt;Photo4 is of a sunset.&lt;br /&gt;Photo7 is of my sister.&lt;br /&gt;Photo0 is of a horse.&lt;br /&gt;Photo10 is of a birthday party.&lt;br /&gt;Photo6 is of a calm lake near the city.&lt;br /&gt;&lt;br /&gt;Putting that idea together with closures, we can hand String.replace() an inner function that uses its parent's static variable to keep count:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function counterAppenderMaker() : Function&lt;br /&gt;{&lt;br /&gt;    var counter : int = 1;&lt;br /&gt;   &lt;br /&gt;    return function() : String { return arguments[0] + counter++ }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var regExp : RegExp = new RegExp( "Photo", "g" );&lt;br /&gt;&lt;br /&gt;text = text.replace( regExp, counterAppenderMaker() );&lt;br /&gt;trace( text );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Which yields this output:&lt;br /&gt;&lt;br /&gt;Photo1 is of a sunset.&lt;br /&gt;Photo2 is of my sister.&lt;br /&gt;Photo3 is of a horse.&lt;br /&gt;Photo4 is of a birthday party.&lt;br /&gt;Photo5 is of a calm lake near the city.&lt;br /&gt;&lt;br /&gt;I think this is an elegant solution. To be fair to OOP, there is another way of doing this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class AppendCounter&lt;br /&gt;{&lt;br /&gt;    private var _counter : int = 1;&lt;br /&gt;   &lt;br /&gt;     public function doIt() : String&lt;br /&gt;    {&lt;br /&gt;        return return arguments[0] + _counter++;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var regExp : RegExp = new RegExp( "Photo", "g" );&lt;br /&gt;var appendCounter : AppendCounter = new AppendCounter();&lt;br /&gt;&lt;br /&gt;text = text.replace( regExp, appendCounter.doIt );&lt;br /&gt;trace( text );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I am not advocating closures over objects (or vice versa), but it's nice to know the closure method. Depending on what I'm trying to achieve, it may be clearer to have all the logic in one class rather than referencing a second class (or a global variable) just to increment a counter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-1065822809377501014?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/1065822809377501014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2010/03/closures-in-actionscript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1065822809377501014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1065822809377501014'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2010/03/closures-in-actionscript.html' title='closures in actionscript'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-6043801014527929164</id><published>2010-01-21T08:26:00.000-08:00</published><updated>2010-01-21T08:44:26.368-08:00</updated><title type='text'>subtleties</title><content type='html'>Whew! I just finished a hell of a debugging session. My goal was to make Flash submit a url to tinyurl.com for minification.&lt;br /&gt;&lt;br /&gt;My code worked locally (when I ran the swf on my desktop), but it didn't work in the browser. So I was pretty sure it was a security issue. But I couldn't understand why I wasn't getting a response from http://tinyurl.com, because they DO have a crossdomain.xml file. See: &lt;a href="http://www.tinyurl.com/crossdomain.xml"&gt;http://www.tinyurl.com/crossdomain.xml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;hint: if you're smarter than I am, you may be able to guess the problem just via the previous paragraph.&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Here's the code that didn't work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;send();&lt;br /&gt;&lt;br /&gt;function send() : void&lt;br /&gt;{&lt;br /&gt;   var url : String = "http://www.google.com/search?q=cows";&lt;br /&gt;   var urlLoader : URLLoader = new URLLoader();&lt;br /&gt;   urlLoader.addEventListener( Event.COMPLETE, receive );&lt;br /&gt;   urlLoader.load( new URLRequest( "http://www.tinyurl.com/api-create.php?url=" + url ) );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//this callback function never gets called!&lt;br /&gt;function receive( event : Event ) : void&lt;br /&gt;{&lt;br /&gt;   var urlLoader : URLLoader = event.target as URLLoader;&lt;br /&gt;   //output is a text field on the stage&lt;br /&gt;   output.text = urlLoader.data;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the working version. Can you spot the difference?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;send();&lt;br /&gt;&lt;br /&gt;function send() : void&lt;br /&gt;{&lt;br /&gt;   var url : String = "http://www.google.com/search?q=cows";&lt;br /&gt;   var urlLoader : URLLoader = new URLLoader();&lt;br /&gt;   urlLoader.addEventListener( Event.COMPLETE, receive );&lt;br /&gt;   urlLoader.load( new URLRequest( "http://tinyurl.com/api-create.php?url=" + url ) );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function receive( event : Event ) : void&lt;br /&gt;{&lt;br /&gt;   var urlLoader : URLLoader = event.target as URLLoader;&lt;br /&gt;   //output is a text field on the stage&lt;br /&gt;   output.text = urlLoader.data;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Give up? The difference is in this statement:&lt;br /&gt;&lt;br /&gt;BUGGY: urlLoader.load( new URLRequest( "http://www.tinyurl.com/api-create.php?url=" + url ) );&lt;br /&gt;&lt;br /&gt;WORKING: urlLoader.load( new URLRequest( "http://tinyurl.com/api-create.php?url=" + url ) );&lt;br /&gt;&lt;br /&gt;In case you still don't see it, the buggy version has a www in-front-of the url and the working version doesn't.&lt;br /&gt;&lt;br /&gt;tinyurl's crossdomain.xml file is located at http://tinyurl.com/crossdomain.xml NOT http://&lt;span style="font-weight:bold;"&gt;www&lt;/span&gt;.tinyurl.com/crossdomain.xml. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;But you'll get to it if you type it the "wrong" way into the browser, because most browser normalize urls.&lt;/span&gt; Flash doesn't. To Flash, there is no crossdomain.xml file, because it was specifically looking for one at the www address, and there isn't one there.&lt;br /&gt;&lt;br /&gt;The scary thing is that my FIRST assumption was that it was a crossdomain.xml issue, so I watched the Activity Window in Safari as I ran my app (the bad version) in the browser. The Activity window showed that the crossdomain file was being accessed correctly. But apparently that was just the BROWSER accessing it correctly. Flash still thought of it as a bogus file, since it came from a www site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-6043801014527929164?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/6043801014527929164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2010/01/subtleties.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6043801014527929164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6043801014527929164'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2010/01/subtleties.html' title='subtleties'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-7621933772209936706</id><published>2010-01-14T08:32:00.000-08:00</published><updated>2010-01-14T08:33:06.053-08:00</updated><title type='text'>how long is an mp3?</title><content type='html'>I need to know the length (in seconds) of a progressive mp3 before it starts playing. As-far-as I can tell, there are only three ways of getting this information:&lt;br /&gt;&lt;br /&gt;1) if it's explicitly stated in some sort of data feed (e.g. an XML playlist), you can, of course, grab that info and hope it's accurate.&lt;br /&gt;&lt;br /&gt;2) you can read it from the id3 tags -- the metadata embedded in the mp3 file itself -- and hope THAT'S accurate.&lt;br /&gt;&lt;br /&gt;3) you can guestimate length using some simple math.&lt;br /&gt;&lt;br /&gt;Option one won't work for me, because my clients are generally not going to enter durations into a data feed. &lt;br /&gt;&lt;br /&gt;I spent hours trying to get option two to work, emailing other developers and asking them for advice. I wasn't receiving the id3 data. Someone mentioned to me that I was likely hitting a security wall. It turns out that though a SWF can play mp3s from another domain, it can't access embedded id3 data without permission. See: http://kb2.adobe.com/cps/963/50c96388.html&lt;br /&gt;&lt;br /&gt;I figured this was the problem, so I added a crossdomain file and a SoundLoaderContext object to Sound.load(), but I still didn't receive any id3 data. Why? Because there wasn't id3 data in the mp3s I was using -- even though the client assured me that there was.&lt;br /&gt;&lt;br /&gt;I realized that I can't count on there being id3 data. Even if there is, there may not be length data, as it's optional which id3 tags are included in an mp3 file (or if any are included at all).&lt;br /&gt;&lt;br /&gt;Which lead me to try option three. I patched it together based on various similar solutions I found online:&lt;br /&gt;&lt;br /&gt;This code runs in a loop:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( _duration == 0 &amp;&amp; ( bytesLoaded / bytesTotal ) &gt; 0.1) &lt;br /&gt;{&lt;br /&gt;    _duration =  _sound.length / 1000 / bytesLoaded * bytesTotal;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It waits until ten percent (0.1) of the mp3 is cashed and then calculates duration. It's an estimate, because it's based on Sound.length, which is NOT necessarily the length of the whole mp3. It's the length of what's loaded so far. &lt;br /&gt;&lt;br /&gt;And you can't simply guess the length from bytesTotal, because depending on the compression/bitrate of the mp3, the same number of bytes could mean different lengths. So the calculation takes into account the known length, the number of bytes loaded so far and the total number of bytes. (Divided by 1000 to convert from milliseconds to seconds.)&lt;br /&gt;&lt;br /&gt;How much should I cache before I let Flash do the calculation? Is ten percent enough? (The JW Player uses ten percent.) I tried it with an mp3 which I knew to be 1 minute and 2 seconds. The guestimation was close but not perfect: 00:59 and 1:00 on subsequent runs. &lt;br /&gt;&lt;br /&gt;I upped the cached-percent to 0.2, which produced perfect guesses. Also, on my high-bandwidth (but not exceptionally high-bandwidth) connection, it took about a second for 0.2 percent to cache, which is acceptable for my purposes.&lt;br /&gt;&lt;br /&gt;But then I tried a one-hour-long mp3. As you might expect, it took quite some time for 20 percent to cache. Totally unacceptable. I changed the percent back to 0.1 and the hour-long mp3 produced a guess in a reasonable amount of time (it took about fifteen seconds to guess). And the guess was only off by one second.&lt;br /&gt;&lt;br /&gt;In the end, I am probably going to use a three-pronged approach: first, I will check for duration data in the XML feed, using that if it's there (doubtful). Next, I will try to use id3 data. Failing both those approaches, I will guestimate with a ten-percent cache. &lt;br /&gt;&lt;br /&gt;If anyone reading this has a better idea, please let me know!&lt;br /&gt;&lt;br /&gt;I am also trying to figure out how to adjust the UI if Flash has to guestimate. When the hour-long mp3 finished playing, the time-duration display said 00:59:00/1:00:00, which doesn't thrill me. Should I fudge the time up to the duration? (if end_time != duratation; then end_time = duration.)&lt;br /&gt;&lt;br /&gt;Someone suggested that I keep checking for duration and adjust it as it the guess gets more accurate (which it will as more data gets cached.) I don't know. I think it would be pretty distracting seeing the the duration-readout change. Also, my played-progress bar would jump around, popping to a longer or shorter width. &lt;br /&gt;&lt;br /&gt;What do you think?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-7621933772209936706?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/7621933772209936706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2010/01/how-long-is-mp3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/7621933772209936706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/7621933772209936706'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2010/01/how-long-is-mp3.html' title='how long is an mp3?'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2563312125156142540</id><published>2009-11-13T13:27:00.000-08:00</published><updated>2009-11-13T14:05:41.715-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>rethinking constructors -- or what I learned from objective-c</title><content type='html'>Like many Flash developers, I've been studying Objective-C in a desperate attempt to ride the iPhone app train. (Though I think it left the station while I was still putting a token in the turnstile.)&lt;br /&gt;&lt;br /&gt;One thing I like about Objective-C is its version of constructors, which usually start with the word "init." For instance, a method might be called just init(), or, if it takes arguments, it might be called initWithColor( 0xFF000 ) or initWithColorAndType( 0xFF0000, "large" );&lt;br /&gt;&lt;br /&gt;Note: objective-C's syntax is different from Actionscript's, so in reality, the last method call above would look like this: [myObject initWithColor: 0xFF0000 andType: @"large"]; Since this post is about Actionscript, I'll keep everything in AS syntax.&lt;br /&gt;&lt;br /&gt;You can, in a sense, overload Objective-C constructors. A class can't have two init() methods. But it can have init(), initWithColor() and initWithColorAndType(). You call the appropriate one, depending on how you want to initialize the object.&lt;br /&gt;&lt;br /&gt;I also like the fact that every Objective-C class has a formal interface (defined in its header file). I do that for my Actionscript classes, too. &lt;br /&gt;&lt;br /&gt;All of my classes (except DTOs and utilities with static members) implement at least one interface. Often, several classes will share the same interface. But even if a class is a loner, I make an interface file for it. I like this this clean separation between interface and implementation. When you browse my code, you can learn how everything fits together just by reading the interface files.&lt;br /&gt;&lt;br /&gt;But you can't define constructors in an interface! That bothers me, because a constructor is -- or can be -- a way of communicating with a class. And if something is part of the way one communicates with a class, it is, by definition, part of that class's interface.&lt;br /&gt;&lt;br /&gt;(I can't use my TV until I first turn it on. So the power button is kind of like a constructor. But it would be insane to say that the power button is not part of the TV's interface.)&lt;br /&gt;&lt;br /&gt;Traditionally, interface files are only used when they are meant to be shared by multiple classes. In that sense, I get why they can't include constructors. Class A and Class B can't share a constructor, because Class A's constructor must be named A() and Class B's must be named B(). &lt;br /&gt;&lt;br /&gt;But since I make separate interface files for each class, I'd like to list ALL class inputs and outputs in those interface files.&lt;br /&gt;&lt;br /&gt;Here's my solution: I never pass ANYTHING into a constructor. In other words, I would never write a constructor like this:&lt;br /&gt;&lt;br /&gt;public function Person( name : String ) { ... }&lt;br /&gt;&lt;br /&gt;Instead, person's constructor will look like this:&lt;br /&gt;&lt;br /&gt;public function Person() { ... }&lt;br /&gt;&lt;br /&gt;I don't care that the Person() method can't be listed in an interface file. It's not used as an interface element. It doesn't suck anything in from the outside world.&lt;br /&gt;&lt;br /&gt;That's not to say I won't write a constructor function. I will if the class has any internal housekeeping it needs to do at start-up:&lt;br /&gt;&lt;br /&gt;public function Person()&lt;br /&gt;{&lt;br /&gt; _kids = new Array();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;So how do I specify that this a Person is named "George"?&lt;br /&gt;&lt;br /&gt;var dad : Person = new Person();&lt;br /&gt;dad.initWithName( "George" );&lt;br /&gt;&lt;br /&gt;If it's also legal to have a nameless person, I would write this:&lt;br /&gt;&lt;br /&gt;var dad : Person = new Person();&lt;br /&gt;person.init();&lt;br /&gt;&lt;br /&gt;All my classes have at least an init() method, even if it is just a placeholder husk. Want to know if my classes can be initialized any other way? Just check their interfaces:&lt;br /&gt;&lt;br /&gt;public class Person implements ILifeform...&lt;br /&gt;&lt;br /&gt;public interface ILifeform&lt;br /&gt;{&lt;br /&gt; function init() : void;&lt;br /&gt; function initWithName( name : String ) : void;&lt;br /&gt; function initWithNameAndGender( name : String, isMale : Boolean );&lt;br /&gt; function eat() : void;&lt;br /&gt; function die() : void;&lt;br /&gt; function die() : void;&lt;br /&gt; function addKid( name : String ) : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;One objection to my system might be that initializer-method names could get absurdly long:&lt;br /&gt;&lt;br /&gt;initWithWarpDriveShieldsPhotonTorpedosHoloDecksAndTransporters( ... );&lt;br /&gt;&lt;br /&gt;To me, that's not an objection -- it's a warning! Even without my system, I would never write code like this:&lt;br /&gt;&lt;br /&gt;var myShip : SpaceShip = new SpaceShip( true, false, true, true, false );&lt;br /&gt;&lt;br /&gt;The more arguments a method takes in, the harder the code is for me to read, and the more apt I am to make a mistake. I have a loose rule of thumb that methods should take in no more than three arguments (and three is really pushing it). &lt;br /&gt;&lt;br /&gt;So I'd change the above long init method to this:&lt;br /&gt;&lt;br /&gt;initWithSpecs( specs : SpaceShipSpecs );&lt;br /&gt;&lt;br /&gt;And I'd back this up with DTO class called ShipSpecs that had properties like warpDrive, sheilds, etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2563312125156142540?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2563312125156142540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/11/rethinking-constructors-or-what-i.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2563312125156142540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2563312125156142540'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/11/rethinking-constructors-or-what-i.html' title='rethinking constructors -- or what I learned from objective-c'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-8682502268960624898</id><published>2009-11-13T12:58:00.000-08:00</published><updated>2009-11-13T13:27:16.282-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript'/><title type='text'>three little tricks</title><content type='html'>Here are a couple of tricks I learned form &lt;a href="http://www.sitepoint.com/blogs/2009/11/12/google-closure-how-not-to-write-javascript/"&gt;this&lt;/a&gt; article:&lt;br /&gt;&lt;br /&gt;I try never to access an array's length in a for loop: &lt;br /&gt;&lt;br /&gt;for ( var i : int = 0; i &lt; people.length; i++ ) ...&lt;br /&gt;&lt;br /&gt;That's bad, because each time the loop iterates, it has to dig into people and access its length property. I get a boost in optimization (without losing clarity) by doing this:&lt;br /&gt;&lt;br /&gt;var numPeople : int = people.length;&lt;br /&gt;for ( var i : int = 0; i &lt; numPeople; i++ ) ...&lt;br /&gt;&lt;br /&gt;But I'm bothered by the fact that both i and numPeople are throw-away variables (just needed for loop mechanics), yet only one is declared outside the for statement. So here's the trick:&lt;br /&gt;&lt;br /&gt;for ( var i : int = 0, numPeople = people.length; i &lt; numPeople; i++ ) ...&lt;br /&gt;&lt;br /&gt;I advocate either that or this:&lt;br /&gt;&lt;br /&gt;var i : int = 0;&lt;br /&gt;var numPeople : int = people.length;&lt;br /&gt;for ( i; i &lt; numPeople; i++ ) ...&lt;br /&gt;&lt;br /&gt;Note: you could also write the for loop this way:&lt;br /&gt;&lt;br /&gt;for ( ; i &lt; numPeople ; i++ )...&lt;br /&gt;&lt;br /&gt;Trick two:&lt;br /&gt;&lt;br /&gt;Let's say you need to loop backwards through an array by index. You could do this:&lt;br /&gt;&lt;br /&gt;var arr : Array = [ 10, 20, 30, 40, 50 ];&lt;br /&gt;for ( var i : int = arr.length - 1; i &lt;= 0; i-- )&lt;br /&gt;{&lt;br /&gt; trace( arr[ i ] );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//output: 50, 40, 30, 20, 10&lt;br /&gt;&lt;br /&gt;or (here's the trick) you could just do this:&lt;br /&gt;&lt;br /&gt;var arr : Array = [ 10, 20, 30, 40, 50 ];&lt;br /&gt;var i : int = arr.length - 1;&lt;br /&gt;while( i-- )&lt;br /&gt;{&lt;br /&gt; trace( arr[ i ] );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//output: 50, 40, 30, 20, 10&lt;br /&gt;&lt;br /&gt;Why does that work? Won't i keep decrementing past zero (-1, -2, -3...)? No, because in the Boolean sense, zero reads as false (all other numbers read as true). So while( 0 ) will stop the loop.&lt;br /&gt;&lt;br /&gt;One final trick:&lt;br /&gt;&lt;br /&gt;I didn't learn this one from the article I liked to above. I've seen it in various places. &lt;br /&gt;&lt;br /&gt;Let's say you want to either set a variable equal to a value read in from an xml file OR, if there is no value in the xml file, you want to set the variable to some default value. (Hint: note the word "or" in the previous sentence.)&lt;br /&gt;&lt;br /&gt;Here's what I used to do:&lt;br /&gt;&lt;br /&gt;if ( valueFromFile == null ) speed = valueFromFile;&lt;br /&gt;else speed = 10; &lt;br /&gt;&lt;br /&gt;or I might have done this:&lt;br /&gt;&lt;br /&gt;speed = ( valueFromFile == null ) ? valueFromFile : 10;&lt;br /&gt;&lt;br /&gt;or even this:&lt;br /&gt;&lt;br /&gt;speed = ( valueFromFile ) ? valueFromFile : 10;&lt;br /&gt;&lt;br /&gt;What I hate about all those versions is the stuttering of "valueFromFile." Via the trick, I can eliminate it like so:&lt;br /&gt;&lt;br /&gt;speed = valueFromFile || 10;&lt;br /&gt;&lt;br /&gt;I love how clean this looks, especially when you're using it with multiple values:&lt;br /&gt;&lt;br /&gt;var speed : int = speedFromFile || 10;&lt;br /&gt;var color : uint = colorFromFike || 0xFF00FF;&lt;br /&gt;var name : String = nameFromFile  || "George";&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-8682502268960624898?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/8682502268960624898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/11/three-little-tricks.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8682502268960624898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8682502268960624898'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/11/three-little-tricks.html' title='three little tricks'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-1433863340580237740</id><published>2009-11-13T12:32:00.000-08:00</published><updated>2009-11-13T12:58:49.543-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript'/><title type='text'>getters and setters: no more faux properties</title><content type='html'>I am obsessed with making my code as easy to use as possible. One way I do that is to stay consistent whenever I can. If class A's kill() method does the same thing as class B's destroy() method, they shouldn't have two different names. They should both be kill() or destroy().&lt;br /&gt;&lt;br /&gt;Adobe is terribly inconsistent (probably due to too many developers working without tight supervision) when deciding if properties should be accessed via methods or faux properties (getters/setters). Is it length or length(). Depends: arrays have length; XMLLists have length(). That always trips me up.&lt;br /&gt;&lt;br /&gt;Accessors can present themselves as either properties or methods. For consistency, I've decided to use only one of these. It doesn't make sense to forgo methods, since I have to use methods for other purposes. So I'm forgoing properties.&lt;br /&gt;&lt;br /&gt;No more "public function get length()" for me. From now on, I'll use getLength() and setLength(). For Booleans, I'll use isCold() and hasChildren(). Anyone using my classes -- including me -- will no longer have to look up a member to see if it's accessed as a property or method. It will always be a method.&lt;br /&gt;&lt;br /&gt;Of course, another clean way of working is to be very rigid about whether a member is something a class has or something a class can do. A class might HAVE length but it can't DO length. I like this distinction in theory, but I'd rather not have to think about it in practice -- especially since some cases are ambiguous: does a book flipTo() page 18 or is its currentPage page 18?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-1433863340580237740?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/1433863340580237740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/11/getters-and-setters-no-more-faux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1433863340580237740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1433863340580237740'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/11/getters-and-setters-no-more-faux.html' title='getters and setters: no more faux properties'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-360808995614503307</id><published>2009-11-06T10:51:00.001-08:00</published><updated>2009-11-06T11:07:49.468-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript events clone'/><title type='text'>Why You Should Override Clone In Event Subclasses</title><content type='html'>When I first learned how to code custom events in Actionscript 3.0, a friend told to override clone() when I subclassed flash.events.Event, but I didn't really understand why. So I ignored his advice. &lt;br /&gt;&lt;br /&gt;It didn't seem to matter. I never wrote my own version of clone() and yet I never ran into any problems. But my friend's advice nagged at me. So I asked him why I should override clone(). He explained that if I didn't, clone() would return the standard Event type rather than my custom event type.&lt;br /&gt;&lt;br /&gt;Let's say I create an Event subclass called KissEvent:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public calls KissEvent extends Event&lt;br /&gt;{&lt;br /&gt;    public var withTongue : Boolean = true;&lt;br /&gt;&lt;br /&gt; public static const BIG_SMOOCH : String = "bigSmooch";   &lt;br /&gt; &lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As usual with events, I can set up a listener for KissEvent:&lt;br /&gt;&lt;br /&gt;this.addEventListener( KissEvent.BIG_SMOOCH, onKiss );&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function onKiss( kissEvent : KissEvent ) : void&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The clone() problem occurs if I try to copy the Event via the clone() method it inherited from flash.events.Event:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function onKiss( kissEvent : KissEvent ) : void&lt;br /&gt;{&lt;br /&gt; var kissEventClone = kissEvent.clone();&lt;br /&gt; &lt;br /&gt; trace( kissEvent.withTongue );&lt;br /&gt; trace( kissEventClone.widthTongue );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first trace, above, will output true. The second will cause an error. Flash will tell me that Event has no such property as withTongue, and in fact it doesn't. Sure, KissEvent has such a property, but clone() doesn't spit out KissEvents; it spits out Events.&lt;br /&gt;&lt;br /&gt;public function clone() : &lt;b&gt;Event&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;And you can't fool it this way:&lt;br /&gt;&lt;br /&gt;trace( ( kissEventClone as KissEvent ).widthTongue );&lt;br /&gt;&lt;br /&gt;Flash won't allow you to cast the clone as a KissEvent, because KissEvents MUST have withTongue properties. clone() spits out Events, which don't have withTongue properties, so there's no way Flash can convert an Event to a KissEvent. My variable name, kissEventClone, is misleading, because it really just holds an Event, not a kissEvent.&lt;br /&gt;&lt;br /&gt;Once my friend explained this to me, I understood the problem, but I had a hard time caring about it. How often do I need to clone an event object? So far in my AS-coding experience, the answer is "never." The problem seems more theoretical than nuts-and-bolts actual.&lt;br /&gt;&lt;br /&gt;But a year later, I encountered the REAL problem: double dispatches.&lt;br /&gt;&lt;br /&gt;Let me explain: sometimes I create systems in which a listener forwards an event object to another listener. The first listener is a sort of middle-man between the dispatcher and the second listener. The middle man is both a listened and a dispatcher. It listens to the event, and, when it receives it, it dispatches the event to a second listener.&lt;br /&gt;&lt;br /&gt;For example, say a game character has to listen for bullets coming at him. If a bullet hits him, he stops the bullet from flying any further and dies. That's the case UNLESS the character is a ghost. If a ghost gets hit by a bullet, it passes right trough him, so he just passes the event on to anything else that might be hit by it. Ghosts, like all characters, listen to Guns. Walls listen to Ghosts, because a Ghost might dispatch a bullet that passed through it, and that bullet might lodge in a wall.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     event                            event&lt;br /&gt;gun (dispatcher) --------------&gt; ghost (dispatcher) ------------&gt; back wall&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Trouble is, a listener can't simply pass on an event. It can only pass on a cloned copy of the event. (That's a built-in "feature" of Flash's event system).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                     event                           event-clone&lt;br /&gt;gun (dispatcher) --------------&gt; ghost (dispatcher) -------------&gt; back wall&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's say that BulletEvents have a custom property called speed. Since clone() outputs Events (not BulletEvents), speed will be passed from gun to ghost but not from ghost to back wall.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                 event (speed=3)                        clone&lt;br /&gt;gun (dispatcher) ---------------&gt; ghost (dispatcher) -----------&gt; back wall&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So if the back wall tries to access speed, it's not going to find anything. Finally understanding the REAL problem, I made sure to override clone() in all my custom events. Here's a toy version of the solution:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyEvent extends Event&lt;br /&gt;{&lt;br /&gt; public var myName : String;&lt;br /&gt; &lt;br /&gt; public static const SOMETHING_HAPPENED : String = "somethingHappened";&lt;br /&gt; &lt;br /&gt; public function MyEvent( type : String, myName : String,&lt;br /&gt;        bubbles : Boolean = true,&lt;br /&gt;        cancelable : Boolean = false )&lt;br /&gt; {&lt;br /&gt;  this.myName = myName;&lt;br /&gt;  super( type, bubbles, cancelable );&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; override public function clone() : Event&lt;br /&gt; {&lt;br /&gt;  return new MyEvent( super.type, myName, super.bubbles, super.cancelable );&lt;br /&gt; }       &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice the overridden clone method. It returns a new MyEvent instance containing all the properties of the current instance. It truly IS a clone!&lt;br /&gt;&lt;br /&gt;The one unfortunate thing is that clone() can't return a MyEvent. It must return an Event. That's because the clone() method in the superclass returns Event, and when you override a superclass's method, your new version must return the same type of object. But the returned Event is created by this statement: new MyEvent( super.type, myName, super.bubbles, super.cancelable ), so it DOES contain the myName property. This means we'll be able to use casting to get at myName, as I'll show below.&lt;br /&gt;&lt;br /&gt;Now that we have our event, I'll show you the dispatcher/listen chain I have in mind:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                  event( w/myName )                            clone( w/myname)&lt;br /&gt;MyEventDispatcher ---------------&gt; MyEventGrabbler (dispatcher) ------------&gt; Main&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the code for MyEventDispatcher:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyEventDispatcher extends EventDispatcher&lt;br /&gt;{&lt;br /&gt; public function dispatch() : void&lt;br /&gt; {&lt;br /&gt;  var myEvent : MyEvent = new MyEvent( MyEvent.SOMETHING_HAPPENED, "Fred" );&lt;br /&gt;  dispatchEvent( myEvent );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the middle-man code for MyEventGrabber:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyEventGrabber extends EventDispatcher&lt;br /&gt;{&lt;br /&gt; private var _myEventDispatcher : MyEventDispatcher;&lt;br /&gt; &lt;br /&gt; public function MyEventGrabber()&lt;br /&gt; {&lt;br /&gt;  _myEventDispatcher = new MyEventDispatcher();&lt;br /&gt;  _myEventDispatcher.addEventListener( MyEvent.SOMETHING_HAPPENED, myHandler );&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public function startTheEventBallRolling() : void&lt;br /&gt; {&lt;br /&gt;  _myEventDispatcher.dispatch();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public function myHandler( myEvent : MyEvent ) : void&lt;br /&gt; {&lt;br /&gt;  dispatchEvent( myEvent );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You might have expected the myHandler method to look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function myHandler( myEvent : MyEvent ) : void&lt;br /&gt;{&lt;br /&gt; dispatchEvent( myEvent.clone() );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;While that's perfectly legal, it's not necessary. (Though maybe it's a good idea, as it makes what's happening explicit). When you re-dispatch an event, Flash uses clone() automatically.&lt;br /&gt;&lt;br /&gt;Finally, here's the section of the Main class that catches the clone and accesses the myName property:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var myEventGrabber : MyEventGrabber = new MyEventGrabber();&lt;br /&gt;myEventGrabber.addEventListener( MyEvent.SOMETHING_HAPPENED, myHandler );&lt;br /&gt;myEventGrabber.startTheEventBallRolling();&lt;br /&gt;&lt;br /&gt;function myHandler( event : Event ) : void&lt;br /&gt;{&lt;br /&gt; trace( (event as MyEvent).myName ); //Fred&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that I use casting here to make Flash understand that the Event is actually a MyEvent. This casting only works because I overrode the clone() method in MyEvent.&lt;br /&gt;&lt;br /&gt;There's one more potential problem that, admittedly, is less serious than the clone() problem. If I replace the above trace with this one...&lt;br /&gt;&lt;br /&gt;trace( event );&lt;br /&gt;&lt;br /&gt;... I won't see the myName property listed. Instead, I'll see this:&lt;br /&gt;&lt;br /&gt;[Event type="somethingHappened" bubbles=true cancelable=false eventPhase=2]&lt;br /&gt;&lt;br /&gt;The simple fix is to also override the toString() property in MyEvent, since when you hand trace() an object, it uses that object's toString() method. The simplest override is this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;override public function toString() : String&lt;br /&gt;{&lt;br /&gt; return "myName=" + myName;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But that will just trace out "myName=Fred", whereas what I want is...&lt;br /&gt;&lt;br /&gt;[Event type="somethingHappened" bubbles=true cancelable=false eventPhase=2 myName="Fred"]&lt;br /&gt;&lt;br /&gt;So I need to append the extra info to the end of the superclass's version of to string:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;override public function toString() : String&lt;br /&gt;{&lt;br /&gt; return super.toString + " myName=" + myName;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Which gives me this:&lt;br /&gt;&lt;br /&gt;[Event type="somethingHappened" bubbles=true cancelable=false eventPhase=2] myName=Fred&lt;br /&gt;&lt;br /&gt;Because I'm anal, I need to get the myName=Fred inside the brackets. I also need to put quotation marks around "Fred," because it's a String. That's all easy to accomplish with a tiny bit of String manipulation. Here's my final version of MyEvent, with a robust toString() method. Note that I have also made a getter for myName, which stops random processes from being able to set myName to values that didn't come from MyEventDispatcher:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyEvent extends Event&lt;br /&gt;{&lt;br /&gt; private var _myName : String;&lt;br /&gt; &lt;br /&gt; public static const SOMETHING_HAPPENED : String = "somethingHappened";&lt;br /&gt; &lt;br /&gt; public function MyEvent( type : String, myName : String,&lt;br /&gt;        bubbles : Boolean = true,&lt;br /&gt;        cancelable : Boolean = false )&lt;br /&gt; {&lt;br /&gt;  _myName = myName;&lt;br /&gt;  super( type, bubbles, cancelable );&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public function get myName() : String&lt;br /&gt; {&lt;br /&gt;  return _myName;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; override public function clone() : Event&lt;br /&gt; {&lt;br /&gt;  return new MyEvent( super.type, _myName, super.bubbles, super.cancelable );&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; override public function toString() : String&lt;br /&gt; {&lt;br /&gt;  var superString = super.toString();&lt;br /&gt;  var newProperties : String = ' myName="' + _myName + '"]';&lt;br /&gt;  &lt;br /&gt;  //removes the closing bracket symbol from the end&lt;br /&gt;  //of the event-property list;&lt;br /&gt;  superString = superString.toString().substr( 0, superString.length - 1 );&lt;br /&gt;  &lt;br /&gt;  return superString + newProperties;&lt;br /&gt; }&lt;br /&gt;        &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The extra two methods, clone() and toString() add a lot of typing to the previously quick job of creating custom events. So I recommend that you use whatever templating system your IDE supports. If you're able to paste in generalized version of those method, it only takes a few seconds to make the necessary changes to support your particular event.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-360808995614503307?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/360808995614503307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/11/why-you-should-override-clone-in-event.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/360808995614503307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/360808995614503307'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/11/why-you-should-override-clone-in-event.html' title='Why You Should Override Clone In Event Subclasses'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-4154676755392476251</id><published>2009-10-02T14:54:00.001-07:00</published><updated>2009-10-02T15:06:42.024-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript cdn'/><title type='text'>SWFS on CDNs</title><content type='html'>The companies that I work for tend to store swf files on CDNs (Content Delivery Networks) which distributes the file over multiple servers. Each server has a copy of the swf, and the one you get, when you visit the company site, might come from any of them. &lt;br /&gt;&lt;br /&gt;This works well except for when I'm making rapid changes to the swf. Each time I make a change, the swf needs to get copied to all of the servers in the network. Until that happens, I can't be sure that everyone is seeing the must current version. Worse, I can't be sure that I'm seeing the most current version. Is my bug fix not working because there's something wrong with it? Or am I seeing the version before the fix.&lt;br /&gt;&lt;br /&gt;The best way to deal with this is not to post constant fixes to the CDN. Test on a single-server site and then upload to the CDN when the app is ready to go live. In theory that works -- and in reality it works for most of the dev cycle -- but in this world of "always in beta," there's now less of distinction between the testing phase and the live phase. (Which sucks and is wrong, wrong, wrong, but I don't run the world.)&lt;br /&gt;&lt;br /&gt;So inevitably I wind up tweaking the swf after it's gone live and is hosted on the CDN. If I find that a change has not propagated to all of the machines on the network, I have to run through a somewhat lengthy set of steps in a web control panel, to make sure that everyone is getting the latest copy. I only want to do this if necessary. Sometimes all the machines get updated as soon as I upload my changes. How can I tell?&lt;br /&gt;&lt;br /&gt;Here's my simple solution:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import flash.ui.ContextMenu;&lt;br /&gt;import flash.ui.ContextMenuItem;&lt;br /&gt;&lt;br /&gt;const APP_VERSION : String = "1.0";&lt;br /&gt;&lt;br /&gt;var menu: ContextMenu = new ContextMenu();&lt;br /&gt;var contextMenuItem : ContextMenuItem = new ContextMenuItem( "app version: " + APP_VERSION );&lt;br /&gt;menu.customItems.push( contextMenuItem );&lt;br /&gt;this.contextMenu = menu;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I put this in my Document class and change the APP_VERSION every time I upload. Then, when I'm looking at it in the browser, I just need to right click on it to see if I'm looking at the most current version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-4154676755392476251?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/4154676755392476251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/10/swfs-on-cdns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4154676755392476251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4154676755392476251'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/10/swfs-on-cdns.html' title='SWFS on CDNs'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2981044174309980590</id><published>2009-09-25T09:22:00.001-07:00</published><updated>2009-09-25T09:23:03.917-07:00</updated><title type='text'>procedural programming in an OOP world</title><content type='html'>Procedural programming is one damn thing after another. The one place I tend to write procedural code is in initialization modules. For instance, say I'm making a video player. The player needs to first load in an xml file that contains configuration info (width, height, background color, etc); then it needs to load in another xml file, containing a playlist; next it needs to load in external graphics; then it needs to render everything to the stage; finally, it needs to play the first video in the playlist.&lt;br /&gt;&lt;br /&gt;What I want to write is something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function init() : void&lt;br /&gt;{&lt;br /&gt; loadConfigData();&lt;br /&gt; parseConfigData();&lt;br /&gt; loadPlaylistData();&lt;br /&gt; parsePlaylistData();&lt;br /&gt; loadGraphics();&lt;br /&gt; renderToStage();&lt;br /&gt; playVideo( 0 );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Alas, asynchronous-loading makes this impossible. My code can't proceed directly from the first step, loadConfigData(), to the second step, parseConfigData(), because it needs to pause and wait for the data to load before it can begin parsing. So I'm forced to use listeners and callback methods.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function loadConfigData() : void&lt;br /&gt;{&lt;br /&gt; var urlLoader : URLLoader = new URLLoader();&lt;br /&gt; urlLoader.addEventListener( Event.COMPLETE, parseConfigData );&lt;br /&gt; urlLoader.load( "config.xml" );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function parseConfigData( event : Event ) : void&lt;br /&gt;{&lt;br /&gt; var urlLoader : URLLoader = event.currentTarget as URLLoader;&lt;br /&gt; var loadedData : String = urlLoader.data;&lt;br /&gt; var xml : XML = XML( loadedData );&lt;br /&gt; &lt;br /&gt; ...&lt;br /&gt; &lt;br /&gt; loadPlaylistData();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My nice, neat, compact procedural list becomes an ugly chain of functions that call other functions:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function stepA() : void&lt;br /&gt;{&lt;br /&gt; //do stuff&lt;br /&gt; stepB();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function stepB() : void&lt;br /&gt;{&lt;br /&gt; //do stuff&lt;br /&gt; stepC();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function stepC() : void&lt;br /&gt;{&lt;br /&gt; //do stuff&lt;br /&gt; stepD();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This sucks, because in order to get a bird's-eye-view of the initialization procedure, I have to scroll through all the code. If I want to stop a function from running -- say during debugging -- I need to search to find where that function is being called. It would be so much easier if I could just do this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function init() : void&lt;br /&gt;{&lt;br /&gt; loadConfigData();&lt;br /&gt; parseConfigData();&lt;br /&gt; loadPlaylistData();&lt;br /&gt; parsePlaylistData();&lt;br /&gt; //loadGraphics();&lt;br /&gt; //renderToStage();&lt;br /&gt; //playVideo( 0 );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I decided to solve this problem by creating a class called StepManager, which allows you to run asynchronous code as if it's synchronous. StepManager takes care of the pause between each step. It knows to run step B only after step A has completed.&lt;br /&gt;&lt;br /&gt;It's very easy to use. You create a (usually) small class for each step. Then you feed the steps to StepManager like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var stepManager : StepManager = new StepManager();&lt;br /&gt;stepManager.addNextStep( StepA );&lt;br /&gt;stepManager.addNextStep( StepB );&lt;br /&gt;stepManager.addNextStep( StepC );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When you're done adding steps, you start them running like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;stepManager.exectute();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you want to be informed of when all the steps are complete, you can add an event listener to stepManager:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var stepManager : StepManager = new StepManager();&lt;br /&gt;stepManager.addEventListener( StepEvent.COMPLETE, stepsCompleteHandler );&lt;br /&gt;stepManager.addNextStep( StepA );&lt;br /&gt;stepManager.addNextStep( StepB );&lt;br /&gt;stepManager.addNextStep( StepC );&lt;br /&gt;&lt;br /&gt;function stepsCompleteHandler( event : StepEvent ) : void&lt;br /&gt;{&lt;br /&gt; trace( "All steps complete." );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To disable a step, you simply comment out the line of code where you added it to the StepManager:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var stepManager : StepManager = new StepManager();&lt;br /&gt;stepManager.addNextStep( StepA );&lt;br /&gt;stepManager.addNextStep( StepB );&lt;br /&gt;//stepManager.addNextStep( StepC );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that StepA, StepB and StepC are classes NOT instances. The StepManager creates instances from the classes you hand it. You just create the classes. Here's the bare bones of what a step class looks like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import com.grumblebee.utilties.stepmanager.AbstractStep;&lt;br /&gt;&lt;br /&gt;    public class StepA extends AbstractStep &lt;br /&gt;    {&lt;br /&gt;        public function StepA( previousStep : AbstractStep = null )&lt;br /&gt;        {&lt;br /&gt;            super( previousStep );&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        override public function execute() : void&lt;br /&gt;        {&lt;br /&gt;   //do stuff&lt;br /&gt;         super.stepComplete();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So to make a step, you just extend AbstractStep, write a simple constructor that takes in one argument (previousStep), and override a function called execute. The guts of your step -- whatever you want the step to do -- go in execute().&lt;br /&gt;&lt;br /&gt;Each step MUST announce when it's done. It does so by calling super.stepComplete(); (Behind the scenes, stepComplete dispatches an event that's received by the StepManager. When it gets that event, StepManager knows it's okay to move onto the next step.)&lt;br /&gt;&lt;br /&gt;Note the previousStep parameter in the constructor. By default, it's set to null. This handles the case of the first step (StepA). There's no step before it, so there can't be a previousStep. But StepManager sends each subsequent step the step that came before it. That way step B can extract any information it needs from step A; Step C can extract information from step B and so on.&lt;br /&gt;&lt;br /&gt;Here's a more complete example:&lt;br /&gt;&lt;br /&gt;Step A holds url of a text file, which it hands to step B. Step B loads in the contents of the text file, which it hands to step C. Step A looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class StepA extends AbstractStep &lt;br /&gt;{&lt;br /&gt;    public function StepA( previousStep : AbstractStep = null )&lt;br /&gt;    {&lt;br /&gt;        super( previousStep );&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public function get urlToLoad() : String&lt;br /&gt;    {&lt;br /&gt;     return "external.txt";&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    override public function execute() : void&lt;br /&gt;    {&lt;br /&gt;     trace( "Step A: It knows the URL of the text file: " + urlToLoad );&lt;br /&gt;     super.stepComplete();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that the new method, urlToLoad(). It's public, so that step B can access it. Step B is a little more complicated. It looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class StepB extends AbstractStep &lt;br /&gt;{&lt;br /&gt;  private var _loadedData : String;&lt;br /&gt;  &lt;br /&gt;     public function StepB( previousStep : AbstractStep = null )&lt;br /&gt;     {&lt;br /&gt;         super( previousStep );&lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt;     public function get loadedData () : String&lt;br /&gt;     {&lt;br /&gt;      return _loadedData;&lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt;     public function set loadedData( value : String ) : void&lt;br /&gt;     {&lt;br /&gt;      _loadedData = value;&lt;br /&gt;      trace( "Step B: storing this loaded data: " + _loadedData );&lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt;     override public function execute() : void&lt;br /&gt;     {&lt;br /&gt;      var stepA : StepA = ( previousStep ) as StepA;&lt;br /&gt;      var url : String = stepA.urlToLoad;&lt;br /&gt;      &lt;br /&gt;      trace( "Step B. received this URL from Step A: " + url );&lt;br /&gt;      &lt;br /&gt;      var urlLoader : URLLoader = new URLLoader();&lt;br /&gt;      urlLoader.addEventListener( Event.COMPLETE, loadCompleteHandler );&lt;br /&gt;      urlLoader.load( new URLRequest( url ) );&lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt;     function loadCompleteHandler( event : Event ) : void&lt;br /&gt;     {&lt;br /&gt;      var urlLoader : URLLoader = event.currentTarget as URLLoader;&lt;br /&gt;      urlLoader.removeEventListener( Event.COMPLETE, loadCompleteHandler );&lt;br /&gt;                 &lt;br /&gt;      loadedData = urlLoader.data;&lt;br /&gt;      &lt;br /&gt;      super.stepComplete();&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Most of the extra stuff here is just the code to load data from an external text file. One detail worth noting how step B gets the url from step A:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; var stepA : StepA = ( previousStep ) as StepA;&lt;br /&gt;  var url : String = stepA.urlToLoad;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Another detail you should note is that step B stores the data from the external file in a variable called _loadedData. It allows the next step to access that data via a getter method:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function get loadedData () : String&lt;br /&gt;{&lt;br /&gt; return _loadedData;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Step C looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class StepC extends AbstractStep &lt;br /&gt;{&lt;br /&gt;    public function StepC( previousStep : AbstractStep = null )&lt;br /&gt;    {&lt;br /&gt;        super( previousStep );&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    override public function execute() : void&lt;br /&gt;    {&lt;br /&gt;     var stepB : StepB = previousStep as StepB;&lt;br /&gt;     trace( "Step C: received text from step B: " + stepB.loadedData );&lt;br /&gt;     super.stepComplete();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note in its execute() method how step C extracts data from step B. &lt;br /&gt;&lt;br /&gt;As shown previously, we can now run all these steps like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var stepManager : StepManager = new StepManager();&lt;br /&gt;           &lt;br /&gt;stepManager.addNextStep( StepA );&lt;br /&gt;stepManager.addNextStep( StepB );&lt;br /&gt;stepManager.addNextStep( StepC );&lt;br /&gt;&lt;br /&gt;stepManager.execute();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the output:&lt;br /&gt;&lt;br /&gt;Step A: It knows the URL of the text file: external.txt&lt;br /&gt;Step B. received this URL from Step A: external.txt&lt;br /&gt;Step B: storing this loaded data: Hi, mom!&lt;br /&gt;Step C: received text from step B: Hi, mom!&lt;br /&gt;All steps complete.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the future, I plan to extend StepManager -- allowing branching as-well-as pause and resume functions. In the meantime, you can download the code (and examples) here: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grumblebee.com/grumblecode/StepManager.zip"&gt;http://www.grumblebee.com/grumblecode/StepManager.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Please let me know if you have any questions or suggestions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2981044174309980590?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2981044174309980590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/09/procedural-programming-in-oop-world.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2981044174309980590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2981044174309980590'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/09/procedural-programming-in-oop-world.html' title='procedural programming in an OOP world'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-3918604562606033324</id><published>2009-09-17T08:55:00.000-07:00</published><updated>2009-09-17T08:56:33.565-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming coding managers clients planning'/><title type='text'>the planning problem</title><content type='html'>Tim Consolazio &lt;a href="http://www.tcoz.com/blogger/2009/09/predictable-irrationality-project.html?showComment=1253202514137#c8895285361064286637"&gt;posted&lt;/a&gt; about the ass-backwards way managers and clients tend to plan user-interfaces. &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;a client has an idea for a project; they want this fantabulous application that does this, this and this. They qualify you, and hire you. There you are, ready to look over requirements and wireframes, iterate through them, allocate your resources, get some preliminary milestones approved, and create a draft project plan.&lt;br /&gt;&lt;br /&gt;The client hands you a few comps; artist renderings of the end result. "That's what I want".&lt;br /&gt;&lt;br /&gt;You're a contractor, so of course, you say "erm...have you considered...". Some internal employee that believes he/she has already foreseen the future is annoyed, but concedes, so they rework the comps. You look it over and say, "hmm...but how about errors and alerts...what about some form of tips or help...what will happen if the user does this..." The designer starts to whine, the client gets tired of hearing you say, "have you considered...", and assigns some internal employee to start pushing you to start dev immediately, believing they because they have shown you a snapshot of the end result, that the plan is ready to go.&lt;br /&gt;&lt;br /&gt;I want to throw a chair across the room and shout, "EVEN IF YOU SUCCEED, YOU ARE GOING TO FAIL!".&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;As a developer, I have to deal with this same frustration. I don't have a solution, but as terrible as it is, I have some sympathy for the people who get exasperated when we say, "Okay, but what about...?" over and over. I'm not saying that they're right (they're not). I'm saying that I understand what motivates them. If there's a solution, it will have to somehow deal with these motivations -- either re-routing them or quashing them.&lt;br /&gt;&lt;br /&gt;When you code, it's generally necessary to plan out a large percentage of what you're going to do before you start -- not the details of the algorithms but all major aspects of the functionality you're coding towards. It's far from trivial to change from one sort of UI to another, so the final UI should be pretty well set before coding begins.&lt;br /&gt;&lt;br /&gt;Trouble is, I don't think this sort of thinking is natural to most people. (It is to some of us coders, but we are the freaks. I mean that in a good way. Our "freakiness" -- our anal-retentive nature -- is one of the things that makes us good at our jobs.)&lt;br /&gt;&lt;br /&gt;Say you're a cave man and you're about to hunt. There are certain things than you definitely plan out beforehand: what weapons to bring, how much food to carry, etc. But you probably don't map out the majority of what you're going to do. You won't say, "first I'm going to look for a leopard; then, if I can't find one after two hours, I'm going to look for a boar..." You'll just go out and hunt, and you'll deal with new situations as they arise. That FEELS right. It's nice to not have to hold too much in your head at once.&lt;br /&gt;&lt;br /&gt;I think that's the natural way (most) people think. They have a general end-goal (bring back food to the cave) and a couple of planned steps (leave cave with spear; walk towards woods), but everything else is improvised.&lt;br /&gt;&lt;br /&gt;It's hard to work in a vacuum, by which I mean that most people need SOMETHING TO RESPOND TO in order to make decisions. And that something should be as physical as possible. A wireframe is pretty abstract. It's not something that you can interact with. The natural way to know if you need an error dialogue is to enter an incorrect value in an ACTUAL form and react the fact that the form doesn't respond. Most managers are probably able to work this way with all the members of their team except for the programmers. "Jennings, draft a memo about our first-quarter earnings ... Hm. Having read your draft, I now see that you need to add a paragraph about salary increases at the bottom of page five..."&lt;br /&gt;&lt;br /&gt;Say I give you a cake recipe. You're reading it over, and I ask, "Do you think we should add more sugar or less?" You'll be tempted to ask, "Can I make the cake the way the recipe says, try it, and get back to you on that?"&lt;br /&gt;&lt;br /&gt;(This is a very similar problem to coding, assuming there isn't time or budget to make second cake. Yes, it is MUCH easier to try a first draft and respond to it, but you don't have that luxury. Since you can only make one cake, and since you can't add or remove sugar from a finished cake, your only option is to plan how much sugar to add at the recipe stage. This is necessary but not ideal.)&lt;br /&gt;&lt;br /&gt;I deal with pre-planning vs. trying-and-reacting when I direct plays, which is my main activity when I'm not programming. When I'm directing, I'm on the other side of the fence. I try to pre-plan as little as possible.&lt;br /&gt;&lt;br /&gt;An actor will say to me, "My scene partner kisses me, and my character is sort of attracted to her but is also married and faithful to his wife. So when I say, 'We can't do this,' do I say it forcefully or sadly?"&lt;br /&gt;&lt;br /&gt;I always respond by saying "Choose one option and lets try the scene." Then I react and we do the scene again, often trying the second alternative. This is a MUCH more natural way to work than to pre-plan many steps ahead.&lt;br /&gt;&lt;br /&gt;I believe we would code this way if we could. If I could whip up a complex app in an hour, I wouldn't ask all the "but what about...?" questions. I would just code exactly what the wireframe suggested, run it up the flagpole and see what happens. Even if it turned out to be total crap, it wouldn't be a major hassle to start over from scratch and have a second draft done in another hour.&lt;br /&gt;&lt;br /&gt;Alas, coding doesn't work like that, so we are forced to think in an un-natural way -- a way that is more about pre-planning than trying and reacting.&lt;br /&gt;&lt;br /&gt;There are other human activities that demand this approach. Architecture is one. You can't just jump in and build a foundation without having first planned out the entire building. This is why architects are rare birds. Not everyone is cut out to be one, because not everyone thinks in this way.&lt;br /&gt;&lt;br /&gt;I'm one of the rare birds who does, and I find that it affects even the way I converse with people.&lt;br /&gt;&lt;br /&gt;Often, people will ask me to do something (not necessarily a programming task), and they'll ask in a vague way -- not fully explaining what they want. For instance, they'll say, "Marcus, would you go get that thing and put it in the closet?"&lt;br /&gt;&lt;br /&gt;What's fascinating to me is to watch how other people tend to deal with requests like this. Over the years, I've noticed that they often don't ask "What thing?" and "Which closet do you mean? We have three."&lt;br /&gt;&lt;br /&gt;They just form a hypothesis (maybe they do this unconsciously) about what the thing is go get it and they randomly put it in one of the three closets.&lt;br /&gt;&lt;br /&gt;The person who make the request later finds the wrong thing in the wrong closet and says, "Sorry, I didn't mean 'put the suitcase in the hall closet', I meant 'put the shoe box in the bedroom closet.'"&lt;br /&gt;&lt;br /&gt;What amazes me -- given my personality type -- is that neither party is upset. They both seem comfortable with a form of communication in which they grope forward from a vague concept to a specific one. &lt;br /&gt;&lt;br /&gt;Whereas I'm much more comfortable with specifics up front. I don't want to waste my time trying to figure out what the thing is and what closet to put it in. So I say, "Sorry, can you tell me what thing you mean and which closet you want me to put it in?" I'm often surprised when my request for specificity is met with irritation. &lt;br /&gt;&lt;br /&gt;But though I'm right to request specificity from the point of view of minimizing confusion and needless work, I'm wrong from the point of view of standard thinking and conversation. My eccentric way of thinking is one of the things that makes me a good coder.&lt;br /&gt;&lt;br /&gt;Getting back to the problem, regardless of what's natural, we CAN'T improvise code. There isn't time. We MUST plan out most of the app before coding begins. That may be unnatural for many people, but it just is the way it is.&lt;br /&gt;&lt;br /&gt;Like I said at the start, I don't have a solution. But I have found some approaches that minimize the problem.&lt;br /&gt;&lt;br /&gt;People who don't think like me hate being boxed in. They hate feeling like they have to come up with a finished plan NOW and that they can't change anything later. I've found that this is generally more of a feeling than an actual business problem. Even if it's unlikely that anything WILL need to change, people still want to feel that they have the option of changing.&lt;br /&gt;&lt;br /&gt;So I usually say this, "Once I'm done coding, there will be some things that will be really easy to change if you don't like them. It will take me five minutes to change the background color or the font or the blah blah blah ... but it will be very expensive to change the dropdown menu to a series of check boxes, so we kind of have to figure that out now..."&lt;br /&gt;&lt;br /&gt;I get much better results if I dole out some flexibility at the same time as I demand specificity. &lt;br /&gt;&lt;br /&gt;We coders also need to keep in mind that non-coders have no idea what's hard to change and what's easy. Why is changing a background trivial while changing a dropdown to a bunch of checkboxes complex? It SEEMS like it should be easy.&lt;br /&gt;&lt;br /&gt;We can't make it easy, but we can warn the people we're working for about the fact that it's not easy. When I do this, I usually acknowledge the fact that this reality is less-than ideal: "UNFORTUNATELY, it's going to be really hard to change X later, so are we sure that's the way we want to go?"&lt;br /&gt;&lt;br /&gt;For programmers and managers to work well together, managers need to understand that programming requires a unique mindset and some un-common planning requirements; meanwhile, programmers need to understand that they are being hired because they are specially gifted at thinking in a non-standard way. They need to learn how to help their co-workers see why things need to be done in a way that is unnatural to them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-3918604562606033324?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/3918604562606033324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/09/planning-problem.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3918604562606033324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3918604562606033324'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/09/planning-problem.html' title='the planning problem'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-8657746536311313026</id><published>2009-09-05T08:14:00.000-07:00</published><updated>2009-09-15T07:13:34.575-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>jquery coding practices</title><content type='html'>I've been the &lt;a href="http://www.lynda.com/"&gt;lynda.com&lt;/a&gt; series on jquery. I learned jquery a year ago, didn't use it, and promptly forgot its syntax. So I'm grateful for the refresher. &lt;br /&gt;&lt;br /&gt;I am curious about what I see as a common practice amongst seasoned jquery-writers: constant use of chaining and function literals. To be blunt, this looks like bad coding style to me. &lt;br /&gt;&lt;br /&gt;This sort of thing I mean:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var whichTag = "h3";&lt;br /&gt;var count = 0;&lt;br /&gt;&lt;br /&gt;$("div:not([id=header]) " + whichTag).each(function() { $(this).html("&lt;a name='bookmark" + count++ + "'&gt;&lt;/a&gt;" + $(this).html() )});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I see this chaining/inline-function style everywhere throughout the jquery community. It's in all the books, tutorials, etc. So I am wondering if there's a good reason for it. I may be stuck in my own rigid paradigm and I'm willing to consider other approaches.&lt;br /&gt;&lt;br /&gt;Here's how I would write that code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;var whichTag = "h3";&lt;br /&gt;var count = 0;&lt;br /&gt;var tagFilter = "div:not[id=header]" + whichTag;&lt;br /&gt;&lt;br /&gt;$each( tagFilter).each( makeAnchor );&lt;br /&gt;&lt;br /&gt;function makeAnchor() &lt;br /&gt;{&lt;br /&gt;        var anchorTag = "&lt;a name='bookmark" + count++ + "'&gt;&lt;/a&gt;";&lt;br /&gt;        var oldTagContent = $html(this);&lt;br /&gt;        $this(html) = anchorTag + oldTagContent;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I would love to hear your thoughts. Is there a profound reason for writing (to me) hard-to-read code when writing it in jquery? Or is it just a convention that has cropped up (why?) in the jquery community?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-8657746536311313026?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/8657746536311313026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/09/jquery-coding-practices.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8657746536311313026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8657746536311313026'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/09/jquery-coding-practices.html' title='jquery coding practices'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-7104386217199933108</id><published>2009-09-01T07:44:00.000-07:00</published><updated>2009-09-01T07:51:21.155-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server cache browser actioncript'/><title type='text'>flash uses the brower's cache</title><content type='html'>Try this code on the Timeline:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;loadEm();&lt;br /&gt;&lt;br /&gt;function loadEm() : void&lt;br /&gt;{&lt;br /&gt; var loader : Loader;&lt;br /&gt; &lt;br /&gt; for ( var i : int = 0; i &lt; 10; i++ )&lt;br /&gt; {&lt;br /&gt;  loader = new Loader();&lt;br /&gt;  loader.contentLoaderInfo.addEventListener( Event.COMPLETE,&lt;br /&gt;                      completeHandler );&lt;br /&gt;  loader.load( new URLRequest( "http://www.nasa.gov/images/content/382654main_s128e006565_full.jpg" ) );&lt;br /&gt;  loader.x = Math.random() * stage.stageWidth;&lt;br /&gt;  loader.y = Math.random() * stage.stageHeight;&lt;br /&gt;  addChild( loader );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function completeHandler( event : Event ) : void&lt;br /&gt;{&lt;br /&gt; var loaderInfo : LoaderInfo =  event.currentTarget as LoaderInfo;&lt;br /&gt; loaderInfo.removeEventListener( Event.COMPLETE, completeHandler );&lt;br /&gt; loaderInfo.content.width = 100;&lt;br /&gt; loaderInfo.content.height = 100;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It loads the same image over and over and places each copy in a random spot on the stage. It's a big image. On my broadband connection, it takes about five seconds to appear.&lt;br /&gt;&lt;br /&gt;I expected the first copy to take a while to load. But I figured it would get cached, and that the subsequent ones would appear instantaneously. But to my surprise, they didn't. When I compiled a test movie, I found I had to wait for each copy to be loaded as it was pulled individually from the sever.&lt;br /&gt;&lt;br /&gt;Then I tried loading the swf into Firefox. Once I ran it in the browser, it behaved as expected: five seconds for the first image and then -- bing! -- the others appeared all at once.&lt;br /&gt;&lt;br /&gt;Firebug confirmed that the swf only make one call to the server. &lt;br /&gt;&lt;br /&gt;For some reason, I thought Flash had its own internal cache. Apparently it doesn't. It uses the brower's cache.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-7104386217199933108?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/7104386217199933108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/09/flash-uses-browers-cache.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/7104386217199933108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/7104386217199933108'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/09/flash-uses-browers-cache.html' title='flash uses the brower&apos;s cache'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2014000217404122047</id><published>2009-08-28T08:07:00.000-07:00</published><updated>2009-08-28T08:08:59.284-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='parameter actionscript order storytelling instances'/><title type='text'>order matters</title><content type='html'>When we code, we constantly have to create instances and set their parameters. How should we order statements when we're creating several instances of the same type? Should we create the instances first and then set their parameters?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var mercury : Planet = new Planet();&lt;br /&gt;var venus : Planet = new Planet();&lt;br /&gt;var earth : Planet = new Planet();&lt;br /&gt;var mars : Planet = new Planet();&lt;br /&gt;&lt;br /&gt;mercury.moons = 0;&lt;br /&gt;venus.moons = 0;&lt;br /&gt;earth.moons = 1;&lt;br /&gt;mars.moons = 2;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or should we group together each instance's creation and settings?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var mercury : Planet = new Planet();&lt;br /&gt;mercury.moons = 0;&lt;br /&gt;&lt;br /&gt;var venus : Planet = new Planet();&lt;br /&gt;venus.moons = 0;&lt;br /&gt;&lt;br /&gt;var earth : Planet = new Planet();&lt;br /&gt;earth.moons = 1;&lt;br /&gt;&lt;br /&gt;var mars : Planet = new Planet();&lt;br /&gt;mars.moons = 2;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or should we group together constructor calls and settings but leave variable declarations separate:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var mercury : Planet;&lt;br /&gt;var venus : Planet;&lt;br /&gt;var earth : Planet;&lt;br /&gt;var mars : Planet;&lt;br /&gt;&lt;br /&gt;mercury = new Planet();&lt;br /&gt;mercury.moons = 0;&lt;br /&gt;&lt;br /&gt;venus = new Planet();&lt;br /&gt;venus.moons = 0;&lt;br /&gt;&lt;br /&gt;earth = new Planet();&lt;br /&gt;earth.moons = 1;&lt;br /&gt;&lt;br /&gt;mars = new Planet();&lt;br /&gt;mars.moons = 2;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I prefer this last approach. It's easiest to read and it groups together the parts of the code I'm most likely to change in tandem. But it's not always possible:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var planets : Array = new [ new Planet(), new Planet(), new Planet(), new Planet() ];&lt;br /&gt;&lt;br /&gt;for each ( var planet : Planet in planets ) planet.moons = Math.floor( Math.random() * 10 );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Also, I'd consider a different type of ordering if parameters values of one instance are related to parameter values of another instance:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var mercury : Planet;&lt;br /&gt;var venus : Planet;&lt;br /&gt;var earth : Planet;&lt;br /&gt;var mars : Planet;&lt;br /&gt;&lt;br /&gt;mercury = new Planet();&lt;br /&gt;mercury.moons = 0;&lt;br /&gt;&lt;br /&gt;venus = new Planet();&lt;br /&gt;venus.moons = 0;&lt;br /&gt;&lt;br /&gt;earth = new Planet();&lt;br /&gt;earth.moons = 1;&lt;br /&gt;&lt;br /&gt;mars = new Planet();&lt;br /&gt;mars.moons = 2;&lt;br /&gt;&lt;br /&gt;mercury.distanceFromSun = 30000000;&lt;br /&gt;venus.distanceFromSun = mercury.distanceFromSun + 30000000;&lt;br /&gt;earth.distanceFromSun = venus.distanceFromSun + 30000000;&lt;br /&gt;mars.distanceFromSun = earth.distanceFromSun + 50000000;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As always, we should remember that the primary job of code is to communicate our intentions to other programmers (sometimes the "other programmer" is the original programmer two months in the future, when he's forgotten his original intentions). So we can often make ordering decisions by thinking about the story we're trying to tell. Compare this ...&lt;br /&gt;&lt;br /&gt;"Once upon a time there lived a beautiful princess, an evil dragon, and a brave knight. The princes was 16 years old; the dragon was 200 years old; the night was 28 years old. The princess had blonde hair; the dragon was bald; the knight had red hair. One day, the princess wandered down to the lake. The dragon liked to eat peasants. The knight fought in many tournaments."&lt;br /&gt;&lt;br /&gt;... with ...&lt;br /&gt;&lt;br /&gt;"Once upon a time there lived a beautiful princess. She was 16 years old and had blond hair. One day she wandered down to the lake. There was also an evil dragon. He was 200 years old, bald, and he liked to eat peasants. Also, there was a brave knight who was 28 years old. He had red hair, and he fought in many tournaments."&lt;br /&gt;&lt;br /&gt;There's no right answer. What's important is to think each case through and decide which approach best communicates your intentions.&lt;br /&gt;&lt;br /&gt;(Thanks &lt;a href="http://www.tcoz.com/blogger/blogger.html"&gt;Tim&lt;/a&gt; for sparking this topic.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2014000217404122047?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2014000217404122047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/order-matters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2014000217404122047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2014000217404122047'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/order-matters.html' title='order matters'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-8921902654158550007</id><published>2009-08-26T08:57:00.001-07:00</published><updated>2009-08-26T08:57:58.272-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript oop variables classes passthrough'/><title type='text'>don't pass variables through classes</title><content type='html'>Sometimes I find myself writing dangerous code like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class UFO&lt;br /&gt;{&lt;br /&gt; public function UFO( alienColor : uint )&lt;br /&gt; {&lt;br /&gt;  var alien = new Alien( alienColor );&lt;br /&gt;  &lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It's dangerous because I'm passing UFO a parameter that it doesn't use. All it does with that parameter is pass it through to Alien's constructor. &lt;br /&gt;&lt;br /&gt;Why is this dangerous? Well, first of all, it makes the code difficult to understand. You're probably not confused my example, above, because I made it purposefully simple. In real-life examples, when I give myself license to pass-through parameters, I tend to pass them through multiple levels:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class UFO&lt;br /&gt;{&lt;br /&gt; public function UFO( alienColor : uint )&lt;br /&gt; {&lt;br /&gt;  var bridge : Bridge = new Bridge( alienColor );&lt;br /&gt;  &lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Bridge&lt;br /&gt;{&lt;br /&gt; public function Bridge( alienColor : uint )&lt;br /&gt; {&lt;br /&gt;  var alien = new Alien( alienColor );&lt;br /&gt;  &lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is also dangerous because it's ugly. You should pass a constructor only the info necessary to construct its class. The construction crew building the UFO and its bridge don't need to know the alien's color.&lt;br /&gt;&lt;br /&gt;Finally, it's ugly because it makes testing difficult. alienColor has multiple chances to get messed up (e.g. set to some illegal value) before it reaches its intended target, Alien.&lt;br /&gt;&lt;br /&gt;So how should I write this code? Well, UFO doesn't need to know anything about an alien's color. It just needs a completed alien so that it has a pilot (to help it destroy the Earth!). So I should first construct an alien and then pass it to UFO.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var alienColor : uint = 0xFF00FF;&lt;br /&gt;var alien : Alien = new Alien( alienColor );&lt;br /&gt;var ufo : UFO = new UFO( alien );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;or, if there's a bridge in the UFO, I should code like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var alienColor : uint = 0xFF0000;&lt;br /&gt;var alien : Alien = new Alien( alienColor );&lt;br /&gt;var bridge : Bridge = new Bridge( alien );&lt;br /&gt;var ufo : UFO = new UFO( bridge );&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-8921902654158550007?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/8921902654158550007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/dont-pass-variables-through-classes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8921902654158550007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8921902654158550007'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/dont-pass-variables-through-classes.html' title='don&apos;t pass variables through classes'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-8911584041679350490</id><published>2009-08-24T08:47:00.000-07:00</published><updated>2009-08-24T09:05:00.499-07:00</updated><title type='text'>how do you integrate library assets into your code?</title><content type='html'>I'm curious as to how folks reference library assets in their code. (I'm talking about Flash projects, not Flex projects). &lt;br /&gt;&lt;br /&gt;I don't know if I'm doing it the wisest way, but I create a package called flaBridge. In that package, I make a class for each library item. Often the class is empty...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package com.grumblebee.project.flaBridge&lt;br /&gt;{&lt;br /&gt;  import flash.display.Sprite;&lt;br /&gt;&lt;br /&gt;  class CompanyLogo extends Sprite&lt;br /&gt;  {&lt;br /&gt;     public function CompanyLogo()&lt;br /&gt;     {&lt;br /&gt;&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I then link to this class in the fla Library.&lt;br /&gt;&lt;br /&gt;This gives me a placeholder for adding specific functionality. It also stops my IDE (FDT) from complaining that I'm referencing classes that don't exist.&lt;br /&gt;&lt;br /&gt;If I'm referencing an instance that's on the fla Stage, I do it this way:&lt;br /&gt;&lt;br /&gt;var logo : CompanyLogo = this[ "logo" ]; //on stage&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-8911584041679350490?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/8911584041679350490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/how-do-you-integrate-library-assets.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8911584041679350490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8911584041679350490'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/how-do-you-integrate-library-assets.html' title='how do you integrate library assets into your code?'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-4848616000580322316</id><published>2009-08-20T13:03:00.000-07:00</published><updated>2009-08-20T13:26:01.499-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='division divided zero NaN Infinity browsers math firefox internetexplorer flash player flashplayer ie'/><title type='text'>NaN != NaN</title><content type='html'>Let's talk about dividing by zero.&lt;br /&gt;&lt;br /&gt;As you probably know, in Math the result of &lt;a href="http://en.wikipedia.org/wiki/Division_by_zero"&gt;dividing a (real) number by zero&lt;/a&gt; is undefined. What is the result of division by zero in AS 3.0?&lt;br /&gt;&lt;br /&gt;It depends. If you divide a number &lt;span style="font-style:italic;"&gt;other than zero&lt;/span&gt; by zero, you get Infinity:&lt;br /&gt;&lt;br /&gt;trace( 10 / 0 ); //Infinity&lt;br /&gt;&lt;br /&gt;trace( 876 / 0 ); //Infinity&lt;br /&gt;&lt;br /&gt;If you divide zero by zero, you get NaN (which stand for "not a number").&lt;br /&gt;&lt;br /&gt;trace( 0 / 0 ); //NaN&lt;br /&gt;&lt;br /&gt;(By the way, to test if the value is NaN, you can't ask "if ( myVar == NaN )." Instead, you have to ask "if ( isNaN( myVar ) )." )&lt;br /&gt;&lt;br /&gt;I learned this nuance recently while trying to fix a weird bug. I was setting the scaleX property of a Sprite. The Sprite was a loader bar, and I was setting its scaleX equal to the percent loaded:&lt;br /&gt;&lt;br /&gt;bar.scaleX = loaded / total;&lt;br /&gt;&lt;br /&gt;When I tested it in Firefox, the bar was totally invisible. I actually expected that, because I hadn't coded the loading process yet. I &lt;span style="font-style:italic;"&gt;thought&lt;/span&gt; I was correctly calculating the total. In other words, I expected loaded / total to be equivalent to something like 0 / 87.&lt;br /&gt;&lt;br /&gt;What I didn't know is that total was also zero. So I was actually doing this...&lt;br /&gt;&lt;br /&gt;bar.scaleX = 0 / 0;&lt;br /&gt;&lt;br /&gt;Which is the same as...&lt;br /&gt;&lt;br /&gt;bar.scaleX = NaN;&lt;br /&gt;&lt;br /&gt;But, like I said, I didn't notice a problem, because the bar was doing what I expected -- showing me that zero percent had loaded by being invisible.&lt;br /&gt;&lt;br /&gt;I noticed the problem when I checked out my SWF in Internet Explorer. (I had Flash Player 10 installed in both IE and Firefox.) In IE, the bar was &lt;span style="font-style:italic;"&gt;not&lt;/span&gt; invisible. It was big. It was so big that it filled up the entire screen!&lt;br /&gt;&lt;br /&gt;Eventually, I figured out that I was dividing zero by zero. That still didn't tell me why I was seeing a giant bar in IE and no bar in Firefox. But when I set the numbers to, say, 10 / 1 or 6 / 0, the bar looked the same in both browsers. Which is when I learned that, in AS 3.0, zero divided by zero is NaN. And it's when I learned that the IE and Firefox plugins treat NaN differently when it's used to set the scaleX value of a Sprite.&lt;br /&gt;&lt;br /&gt;Why would you want to scale a Sprite to NaN? Hopefully, you wouldn't. I did it by accident.&lt;br /&gt;&lt;br /&gt;In both browsers, you get fill-the-whole-screen Sprites if you set scaleX to Infinity (which I guess makes sense: the Sprite gets infinitely wide). So my guess is that in Firefox, sprites interpret a scaleX of NaN as zero, whereas in IE they interpret it the same way they interpret Infinity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-4848616000580322316?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/4848616000580322316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/nan-nan.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4848616000580322316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4848616000580322316'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/nan-nan.html' title='NaN != NaN'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2237495049430860077</id><published>2009-08-18T07:46:00.001-07:00</published><updated>2009-08-18T08:09:49.940-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='null debugging escape unescape conditional'/><title type='text'>when null is not null</title><content type='html'>Having just left the debugging Twilight Zone, I am going to post my findings so that others can profit from my woes. &lt;br /&gt;&lt;br /&gt;I had a simple if statement like this:&lt;br /&gt;&lt;br /&gt;if ( someValue == null ) trace( "null" );&lt;br /&gt;else ( trace( "not null" );&lt;br /&gt;&lt;br /&gt;I expected the value to be null, so I was surprised to see "not null" appear in the output window.&lt;br /&gt;&lt;br /&gt;To check my sanity, I added a trace above the conditional:&lt;br /&gt;&lt;br /&gt;trace( "someValue == ", someValue );&lt;br /&gt;if ( someValue == null ) trace( "null" );&lt;br /&gt;else ( trace( "not null" );&lt;br /&gt;&lt;br /&gt;To my horror, I got this:&lt;br /&gt;&lt;br /&gt;someValue ==   null&lt;br /&gt;not null&lt;br /&gt;&lt;br /&gt;After half an hour of tripping in Bizarro World, I noticed those extra spaces before the word "null" in the first trace. This prompted me to take a look at someValue's declaration:&lt;br /&gt;&lt;br /&gt;var someValue : String = myFlashVars.someValue;&lt;br /&gt;&lt;br /&gt;myFlashVars is, as you might guess, an object containing all the flashVars. I expected someValue to be null, because, while testing, I wasn't passing any vars into the swf.&lt;br /&gt;&lt;br /&gt;Okay, I lied. The declaration wasn't this...&lt;br /&gt;&lt;br /&gt;var someValue : String = myFlashVars.someValue;&lt;br /&gt;&lt;br /&gt;... it was this:&lt;br /&gt;&lt;br /&gt;var someValue : String = unescape( myFlashVars.someValue );&lt;br /&gt;&lt;br /&gt;Since myFlashVars got set with URL variables (e.g. http://myapp.swf?someValue=foo), I wanted to make sure that any escaped characters in someValue got converted to unescaped ones.&lt;br /&gt;&lt;br /&gt;But this causes a problem when there is no myFlashVars.someValue. If there is no myFlashVars.someValue, then myFlashVars.someValue = null.&lt;br /&gt;&lt;br /&gt;And, apparently, if you unescape null, you get the string "   null".&lt;br /&gt;&lt;br /&gt;So my conditional was testing whether "   null" is equal to null. And of course it's not.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2237495049430860077?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2237495049430860077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/when-null-is-not-null.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2237495049430860077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2237495049430860077'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/when-null-is-not-null.html' title='when null is not null'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-1044464073136535703</id><published>2009-08-12T12:24:00.000-07:00</published><updated>2009-08-12T12:25:35.594-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='constructor interface'/><title type='text'>keep logic out of constructors</title><content type='html'>I'm sometimes tempted to overstuff constructors:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class AxeMurderer&lt;br /&gt;{&lt;br /&gt; private var _name : String;&lt;br /&gt; private var _crazy : Boolean;&lt;br /&gt; &lt;br /&gt; public function AxeMurderer( name : String, crazy : Boolean )&lt;br /&gt; {&lt;br /&gt;  _name = name;&lt;br /&gt;  _crazy = crazy;&lt;br /&gt;  &lt;br /&gt;  if ( _crazy )&lt;br /&gt;  {&lt;br /&gt;   for ( var i : int = 0; i &lt; 10000; i++ )&lt;br /&gt;    trace( "all work and no play makes Jack a dull boy" );&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The overstuffing is the for loop (and possibly the conditional). I clean things up a bit by refactoring to...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class AxeMurderer&lt;br /&gt;{&lt;br /&gt; private var _name : String;&lt;br /&gt; private var _crazy : Boolean;&lt;br /&gt; &lt;br /&gt; public function AxeMurderer( name : String, crazy : Boolean )&lt;br /&gt; {&lt;br /&gt;  _name = name;&lt;br /&gt;  _crazy = crazy;&lt;br /&gt;  &lt;br /&gt;  if ( _crazy ) writeManifesto();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function writeManfesto() : void&lt;br /&gt; {&lt;br /&gt;  for ( var i : int = 0; i &lt; 10000; i++ )&lt;br /&gt;   trace( "all work and no play makes Jack a dull boy" );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But this creates a problem when I write an interface for the class. &lt;br /&gt;&lt;br /&gt;Let me pause to say that I try to write my interfaces first, before writing the classes that implement them. That way I'm coding TO an interface. However, in real life that doesn't always happen. Sometimes I can't work out an interface without first writing at least a dummy implementation. In such cases, I go back and write an interface later. At least that I way I have the interface for similar classes. &lt;br /&gt;&lt;br /&gt;So, having written the AxeMurderer class, I decide to create an IMurderer interface -- one that has a slightly broader scope than just axe murderers:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IMurderer&lt;br /&gt;{&lt;br /&gt; //Hmmmm....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What do I put inside the interface? Looking back at my AxeMurderer class, the only public method is the constructor. That's because I got tempted by a (anti?) pattern: make the constructor build the object by calling a bunch of private methods.&lt;br /&gt;&lt;br /&gt;So the interface would be...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IMurderer&lt;br /&gt;{&lt;br /&gt; function AxeMurderer( name : String, crazy : Boolean )&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But that would force any class that implemented it to have an AxeMurderer method -- terribly inappropriate for a Poisoner or a Strangler!&lt;br /&gt;&lt;br /&gt;So, assuming that all types of murders might write a manifesto, I'm going to change my interface to...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IMurderer&lt;br /&gt;{&lt;br /&gt; function writeManifesto() : void;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(I'm using a short example to illustrate a point. A real-life IMurderer would insist on methods like Kill(), Spare(), Escape(), Surrender() and BlameItOnJunkFood().)&lt;br /&gt;&lt;br /&gt;Now I'll rewrite AxeMurderer as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class AxeMurderer implements IMurderer&lt;br /&gt;{&lt;br /&gt; private var _name : String;&lt;br /&gt; private var _crazy : Boolean;&lt;br /&gt; &lt;br /&gt; public function AxeMurderer( name : String, crazy : Boolean )&lt;br /&gt; {&lt;br /&gt;  _name = name;&lt;br /&gt;  _crazy = crazy;&lt;br /&gt;  &lt;br /&gt;  if ( _crazy ) writeManifesto();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //NOTE: Method now public&lt;br /&gt; public function writeManfesto() : void&lt;br /&gt; {&lt;br /&gt;  for ( var i : int = 0; i &lt; 10000; i++ )&lt;br /&gt;   trace( "all work and no play makes Jack a dull boy" );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that I'm still calling writeManifesto() in the constructor. That's fine. Some IMurderer classes may choose to automatically write a manifesto; others may choose to only write one if writeManifesto() is called by an external client.&lt;br /&gt;&lt;br /&gt;In general, I try to use constructors just for getting necessary external data into the class. Class logic goes elsewhere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-1044464073136535703?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/1044464073136535703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/keep-logic-out-of-constructors.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1044464073136535703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1044464073136535703'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/keep-logic-out-of-constructors.html' title='keep logic out of constructors'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-3695655984243343963</id><published>2009-08-10T12:51:00.000-07:00</published><updated>2009-08-10T13:09:32.085-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='inheritance super variables'/><title type='text'>a super solution</title><content type='html'>Like many developers, I &lt;a href="http://www.artima.com/lejava/articles/designprinciples4.html"&gt;favor Composition over Inheritance&lt;/a&gt;. Still, subclassing is a powerful tool, and I can't imagine abandoning it altogether. Knowing its pifalls, I try to make my intentions as clear as possible when I choose to use Inheritance.&lt;br /&gt;&lt;br /&gt;When I read other-people's code, I tend to get confused by inherited variables. Say I'm skimming over a class with three members: width, height and color. I read method after method that mentions these members. Then all of the sudden, one lone method mentions position.&lt;br /&gt;&lt;br /&gt;Huh? What's position? Why haven't I seen it before? I scroll around, looking for its definition, but I don't find it. Finally, I remember that I'm looking at a subclass. "Oh! Maybe position is defined in its parent class." I flip over to that class and, sure enough, there's position's declaration. (This must be a total nightmare in languages that support multiple inheritance.)&lt;br /&gt;&lt;br /&gt;But I've now wasted brain cells on something other than the task at hand (whatever that was). I shouldn't have to go searching for vars. &lt;br /&gt;&lt;br /&gt;To fix this in my own code, I'm going to start labeling inherited vars as with the prefix "super."&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function foo() : void&lt;br /&gt;{&lt;br /&gt;  var someValue : Number = width + super.position.x;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If I look at code like that, I know exactly where position comes from.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-3695655984243343963?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/3695655984243343963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/super-solution.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3695655984243343963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3695655984243343963'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/super-solution.html' title='a super solution'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-8240686682127364877</id><published>2009-08-10T08:24:00.001-07:00</published><updated>2009-08-10T08:24:45.325-07:00</updated><title type='text'>what a drag</title><content type='html'>Like most developers, I make little shortcut utilities to help me bypass repetitive tasks. For some reason, though, I'd never bothered to come up with a solution for the tedious work of drag and drop. Nor have I researched anyone else's solution. But recently, I've had to make a lot of Sprites and MovieClips draggable. After the fifth or sixth time I'd added and removed a bunch of listeners, I thought "There's got to be an easier way."&lt;br /&gt;&lt;br /&gt;I thought of two: the first was to extend Sprite, creating DraggableSprite. The second was to make a separate class that only handled dragging and leave Sprite's many other duties to Sprite itself. I settled on the latter, reasoning that Sprite was already bloated enough. &lt;br /&gt;&lt;br /&gt;Before sharing my solution, let me outline the steps needed to make a Sprite draggable. First, you need a way to detect when the user has mouse-downed on the Sprite. So you have to add a listener for that.&lt;br /&gt;&lt;br /&gt;Inside that listener's callback function, you can go head and call startDrag() on the Sprite. But you also need to remove the MOUSE_DOWN listener, because while the user is dragging the Sprite, listening for mouse downs is just burning computer cycles for nothing.&lt;br /&gt;&lt;br /&gt;Meanwhile, you have add a listener for MOUSE_MOVE (in case you need to know when the Sprite moves, as you for the thumb control on a slider or scrollbar). You also need to add two MOUSE_UP listeners, one to the Sprite and one to the stage. The stage listener traps for the the user rolling off the Sprite before releasing his mouse button.&lt;br /&gt;&lt;br /&gt;In the MOUSE_UP handler, you call stopDrag(), remove all of the above listeners, and re-add the MOUSE_DOWN listener, so that the process can start all over again.&lt;br /&gt;&lt;br /&gt;These steps aren't too bad, unless you wind up having to do them over and over. Compare them with using my DragManager class, which you instantiate this way:&lt;br /&gt;&lt;br /&gt;var dragManager : DragManager = new DragManger( mySprite );&lt;br /&gt;&lt;br /&gt;That's it. mySprite is now dragabble. If you want control over the optional parameters of startDrag() -- lockCenter and bounds -- just pass them to the Dragmanager constructor as additional parameters:&lt;br /&gt;&lt;br /&gt;var dragManager : DragManager = new DragManger( mySprite, true, myRect );&lt;br /&gt;&lt;br /&gt;Note: lockCenter defaults to false; bounds defaults to null.&lt;br /&gt;&lt;br /&gt;Of course, you usually want to do more than just make a Sprite or MovieClip draggable. You also want to know when it starts being dragged, where it moves, and when it stops being dragged. You can detect these things by adding listeners to the DragManager instance.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var dragManager : DragManager = new DragManger( mySprite );&lt;br /&gt;draggManager.addEventListener( DragManager.START_DRAG, handler );&lt;br /&gt;draggManager.addEventListener( DragManager.DRAG, handler );&lt;br /&gt;draggManager.addEventListener( DragManager.STOP_DRAG, handler );&lt;br /&gt;&lt;br /&gt;function handler( event : Event ) : void&lt;br /&gt;{&lt;br /&gt; trace( event.type, event.currentTarget.dragger.name );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you run this code, you'll see the following output as you drag and drop your Sprite:&lt;br /&gt;&lt;br /&gt;startDrag mySprite&lt;br /&gt;drag mySprite&lt;br /&gt;drag mySprite&lt;br /&gt;drag mySprite&lt;br /&gt;drag mySprite&lt;br /&gt;drag mySprite&lt;br /&gt;stopDrag mySprite&lt;br /&gt;&lt;br /&gt;Note that, inside the handler, you can get access to the Sprite being dragged by referencing event.CurrentTarget.dragger.&lt;br /&gt;&lt;br /&gt;DragManager has a couple of other tricks up its sleeve. You can disable dragging by calling disableDrag() and re-enable it by calling enableDrag(). You can also re-use the same DragManager by changing which object it controls:&lt;br /&gt;&lt;br /&gt;var dragManager : DragManager = new DragManger( myMovieClip );&lt;br /&gt;&lt;br /&gt;//later&lt;br /&gt;&lt;br /&gt;dragManager.sprite = mySprite;&lt;br /&gt;&lt;br /&gt;Note: ordinarily, I wouldn't bother being this thrifty. If I want to make both a Sprite and MovieClip draggable, I just do this:&lt;br /&gt;&lt;br /&gt;var spriteDragManager : DragManager = new DragManger( mySprite );&lt;br /&gt;var movieClipDragManager : DragManager = new DragManger( myMovieClip );&lt;br /&gt;&lt;br /&gt;But the previous approach is useful if you want only one of the objects to be draggable. DragManagers can manage multiple objects, but only one at a time.&lt;br /&gt;&lt;br /&gt;Other properties include lockCenter and bounds, which you can use if you want to change aspects of the drag after it's started. Note that if you do this, you need to disable and re-enable the drag to make the changes take effect:&lt;br /&gt;&lt;br /&gt;var dragManager : DragManager = new DragManger( mySprite );&lt;br /&gt;&lt;br /&gt;//later&lt;br /&gt;&lt;br /&gt;dragManager.disableDrag();&lt;br /&gt;dragManager.lockCenter = true;&lt;br /&gt;dragManager.bounds = new Rectangle( 20, 100, 200, 0 );&lt;br /&gt;dragManager.enableDrag();&lt;br /&gt;&lt;br /&gt;Note: disableDrag() removes all listeners from the Sprite, so it's a good cleanup method for eliminating CPU-hogging processes.&lt;br /&gt;&lt;br /&gt;It's such a joy to write classes like DragManager. Or, rather, it's a joy to HAVE written them. Once they're done and tested, you know you've cut a piece of tedium out of your life. &lt;br /&gt;&lt;br /&gt;Here's the code: &lt;a href="http://www.grumblebee.com/grumblecode/DragManager.zip"&gt;http://www.grumblebee.com/grumblecode/DragManager.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-8240686682127364877?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/8240686682127364877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/what-drag.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8240686682127364877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8240686682127364877'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/what-drag.html' title='what a drag'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-8454596781589167526</id><published>2009-08-05T09:32:00.000-07:00</published><updated>2009-08-05T09:33:24.583-07:00</updated><title type='text'>on the use of constructors</title><content type='html'>I've tried constructing objects in every way imaginable. After reading many books, blog-posts and essays about best-practices, I was swayed by people who argued that the all data an object needs should be fed to it via its constructor. Before coming to that conclusion, I used to write lots of parameter-initialization methods.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Spaceship extends Sprite&lt;br /&gt;{&lt;br /&gt; private var _hullColor : uint;&lt;br /&gt; private var _hasLaser : Boolean;&lt;br /&gt; private var _laserColor : uint;&lt;br /&gt; &lt;br /&gt; ... more private properties ...&lt;br /&gt;&lt;br /&gt; public function set hullColor ( value : uint ) : void&lt;br /&gt; {&lt;br /&gt;  _hullColor = value;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public function set hasLaser( value : uint ) : void&lt;br /&gt; {&lt;br /&gt;  _hasLaser = value;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public function set laserColor( value : uint ) : void&lt;br /&gt; {&lt;br /&gt;  _laserColor = value;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; ... more setter methods ...&lt;br /&gt; &lt;br /&gt; public function render() : void&lt;br /&gt; {&lt;br /&gt;  ... code that draws the space ship ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Using this method, I'd create a Space-ship instance as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var ussValiant : SpaceShip = new SpaceShip();&lt;br /&gt;ussValiant.hullColor = 0x666666;&lt;br /&gt;ussValiant.hullShape = HullShape.CIGAR;&lt;br /&gt;ussValiant.hasLasers = true;&lt;br /&gt;ussValiant.laserColor = 0x00cc00;&lt;br /&gt;ussValiant.hasBridge = true;&lt;br /&gt;ussValiant.bridgeColor = 0x666666;&lt;br /&gt;ussValiant.bridgeShape = BridgeShapes.SPHERE;&lt;br /&gt;ussValiant.bridgeSize = BridgeSizes.large;&lt;br /&gt;&lt;br /&gt;ussValiant.render();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The trouble here is that it's impossible to tell whether or not I need to set all the parameters or if some of them are optional. Do I need to set them in a particular order? What happens if I set one after calling render? To even know about all the parameters, I have to read through the whole class's API. If, instead, I set all necessary parameters via a constructor, a quick glance at its heading will tell me everything I need to know about parameter order and requirements:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function SpaceShip( hullColor : uint, hullShape : uint, hasLasers : Boolean = false,&lt;br /&gt;       laserColor : uint = 0, hasBridge : Boolean = false,&lt;br /&gt;       bridgeColor : uint = 0, bridgeShape : String = "sphere",&lt;br /&gt;       bridgeSize = "small" )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The obvious downside to this approach is the unwieldy number of parameters that are stuffed inside the constructor's parentheses. It was this very problem that originally convinced me to write all those setters. I hate overstuffing a constructor, because constructors should take, at most, three parameters. &lt;br /&gt;&lt;br /&gt;Why three? Well, it's not a hard and fast rule. It's just an aesthetic. Three, because it's relatively easy to remember three things. After that, it gets harder, at least for my poor, addled brain. Constructors that take four or more parameters are hard to use and hard to read without confusion. Compare the following:&lt;br /&gt;&lt;br /&gt;THE BEST KIND OF CONSTRUCTOR:&lt;br /&gt;var puppy : Puppy = new Puppy();&lt;br /&gt;&lt;br /&gt;A VERY GOOD CONSTRUCTOR:&lt;br /&gt;var name : String = "Fred";&lt;br /&gt;var monster : Monster = new Monster( name );&lt;br /&gt;&lt;br /&gt;A PERTTY GOOD CONSTRUCTOR:&lt;br /&gt;var bread : String = BreadTypes.RYE;&lt;br /&gt;var meat : String = MeatTypes.TURKEY;&lt;br /&gt;var hasMayo : Boolean = true;&lt;br /&gt;var sandwich : Sandwich = new Sandwhich( bread, meat, hasMayo );&lt;br /&gt;&lt;br /&gt;A DUBIUS CONSTRUCTOR:&lt;br /&gt;var hasMilk : Boolean = false;&lt;br /&gt;var hasSugar : Boolean = true;&lt;br /&gt;var isIced : Boolean = false;&lt;br /&gt;var size : String = CoffeeSizes.GRANDE;&lt;br /&gt;var coffee : Coffee = new Coffee( hasMilk, hasSugar, isIced, size );&lt;br /&gt;&lt;br /&gt;A TERRIBLE CONSTRUCTOR:&lt;br /&gt;var title : String = "Lonesome Parrot";&lt;br /&gt;var genre : GenreTypes.WESTERN;&lt;br /&gt;var stars : Array = [ "Ian McShane", "Michelle Pfeiffer" ];&lt;br /&gt;var director : String = "Stephen Spielberg";&lt;br /&gt;var writer : String = "Thomas Kenneally";&lt;br /&gt;var budget : Number = 50000000;&lt;br /&gt;var hasSequel : Boolean = true;&lt;br /&gt;var movie : Movie = new Movie( title, genre, stars, director, writer, budget, hasSequel );&lt;br /&gt;&lt;br /&gt;When faced with the prospect of a terrible constructor, it's tempting to just pass it a value object:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MovieData&lt;br /&gt;{&lt;br /&gt; public var title : String;&lt;br /&gt; public var genre : String;&lt;br /&gt; public var stars : Array;&lt;br /&gt; public var director : String;&lt;br /&gt; public var writer : String;&lt;br /&gt; public var budget : Number;&lt;br /&gt; public var hasSequel : Boolean = true;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The benefit here is that the constructor now only needs to take in one parameter:&lt;br /&gt;&lt;br /&gt;var movie : Movie = new Movie( movieData : MovieData );&lt;br /&gt;&lt;br /&gt;The problem with this approach is that the constructor has lost its power to communicate. From looking at its signature, all I know is that it takes in some vague sort of data. I have to look at the value-object class to learn more. And looking at that still doesn't tell me whether or not I need to give every parameter a value or if some are optional.&lt;br /&gt;&lt;br /&gt;Sometimes, this is the best I can do. But usually, I can solve this problem by breaking up the class into several smaller classes. In fact, when I feel the need to pass a constructor many parameters -- via raw values or through a value object -- I take it as a sign that my thinking isn't granular enough. &lt;br /&gt;&lt;br /&gt;For instance, does it really make sense to have just one monolithic movie class? At the very least, I can break it up into Movie, Metadata and Staff:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Staff&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; public function Staff( director : String, writer, String, stars : Array )&lt;br /&gt; {&lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Metadata&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt; &lt;br /&gt; public function Metadata( title : String, genre : String, budget : Number, &lt;br /&gt;        hasSequel : Boolean = false )&lt;br /&gt; {&lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt;        &lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Movie&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt; &lt;br /&gt; public function Movie( metadata : Metadata, staff : staff )&lt;br /&gt; {&lt;br /&gt;   ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I'm not crazy about the Metadata class, because it has four parameters, which violates my aesthetic limit. Perhaps I'll leave it as is, though. I'm not dogmatic about the three-parameter rule. However, looking at the parameters, I do have a vague feeling that "budget" is a different sort of beast from "title", "genre" and "hasSequel". I might consider creating a new class called Finances or at least keep that option open in my mind. I know for sure that I don't want to add any more parameters to Metadata! Maybe Metadata itself should take in three parameters, category (title and genre), hasSequels and finances( budget ). Or maybe Metadata should only be about the title, genre and sequels. Maybe Movie should take in metadata, staff and finances.&lt;br /&gt;&lt;br /&gt;Regardless of my ultimate decision, my gaol is to keep everything small: small number of parameters, small methods and small classes. Small is good, because small is readable; small is easy to maintain. &lt;br /&gt;&lt;br /&gt;This super-modular approach mirrors the way we think. If I ask you to tell me about your best friend, you might say, "His name is Bob. He's a lab technician." Translated to OOP, that's...&lt;br /&gt;&lt;br /&gt;var bestFriend : Person = new Person( "Bob", "lab technician" );&lt;br /&gt;&lt;br /&gt;But what if I ask you to describe Bob in more detail. You're likely to say something like, "Well, he's been married for ten years and he has a little girl named Sarah. He has brown hair and green eyes. He lives in Seattle." Notice how you broke down your description into categories. You're didn't amorphously describe Bob. You specifically told me about his family, his looks and his location.&lt;br /&gt;&lt;br /&gt;You're didn't do this:&lt;br /&gt;&lt;br /&gt;var bestFriend : Person = new Person( "Bob", "lab technician", 10, "Sarah", "brown", "green", "Seattle" );&lt;br /&gt;&lt;br /&gt;You did this:&lt;br /&gt;&lt;br /&gt;var family : Family = new Family( 10, ["Sarah"] );&lt;br /&gt;var looks : Looks = new Looks( "green", "brown" );&lt;br /&gt;var location : Location = new Location( "Seattle" );&lt;br /&gt;var bestFriend : Person = new Person( "Bob", "Lab Technician", family, looks, location );&lt;br /&gt;&lt;br /&gt;That's two too-many parameters, but it's more readable and natural than the former version. Maybe name, occupation and looks could be bundled into a class called Description. That would give you...&lt;br /&gt;&lt;br /&gt;var bestFriend : Person = new Person( description, family, location );&lt;br /&gt;&lt;br /&gt;The goal isn't to come up with the perfect solution. There isn't a perfect solution. The gaol is to continually play around to make your code as simple and communicative as possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-8454596781589167526?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/8454596781589167526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/on-use-of-constructors.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8454596781589167526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8454596781589167526'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/on-use-of-constructors.html' title='on the use of constructors'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-6655308526956966539</id><published>2009-08-03T07:59:00.000-07:00</published><updated>2009-08-03T11:28:11.242-07:00</updated><title type='text'>adobe's mistake: displayObjects need interfaces</title><content type='html'>Last week, I wrote a function that drew a randomly-colored circle on a Sprite:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function randomColoredCircle( target : Sprite ) : void&lt;br /&gt;{&lt;br /&gt; var color : uint = Math.round( Math.random() * 0xFFFFFF );&lt;br /&gt; var xPosition : Number = 0;&lt;br /&gt; var yPosition : Number = 0;&lt;br /&gt; var radius : Number = 30;&lt;br /&gt; &lt;br /&gt; target.graphics.beginFill( color );&lt;br /&gt; target.graphics.drawCircle( xPosition, yPosition, radius );&lt;br /&gt; target.graphics.endFill();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To call this function, all I had to do was hand it a Sprite to draw on:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var sprite : Sprite = new Sprite();&lt;br /&gt;&lt;br /&gt;randomColoredCircle( sprite );&lt;br /&gt;&lt;br /&gt;addChild( sprite );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This worked fine until I suddenly needed to draw a circle on a MovieClip. I couldn't hand a MovieClip to the function, because it specifically requests Sprites:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function randomColoredCircle( target : Sprite ) : void //won't accept a MovieClip&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;NOTE: a commenter pointed out that MovieClips do, in fact, inherit from the Sprite class, so the above function will work. However, as you'll see (below), the Shape class does not extend Sprite (or vice versa), so the problem remains.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The worst possible solution to this problem is to make another version of the function that's exactly the same, except it draws on MovieClips:&lt;br /&gt;&lt;br /&gt;BAD:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function randomColoredCircleOnSprite( target : Sprite ) : void { ... }&lt;br /&gt;function randomColoredCircleOnMovieClip( target : MovieClip ) : void { ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Using this approach, I might have to make a third function that draws circles on Shapes. Ugh! This is begging for trouble. What if I decide to make the circles smaller? I would have to remember to update "var radius : Number = 30" in all three functions. &lt;br /&gt;&lt;br /&gt;Here's a better solution -- one I would advocate if Actionscript wasn't an object-oriented langiage:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function randomColoredCircleOnSPRITE( target : Sprite ) : void &lt;br /&gt;{&lt;br /&gt; var canvas : Graphics = target.graphics;&lt;br /&gt; randomColoredCircle( canvas );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function randomColoredCircleOnMOVIECLIP( target : MovieClip ) : void &lt;br /&gt;{  &lt;br /&gt; var canvas : Graphics = target.graphics;&lt;br /&gt; randomColoredCircle( canvas );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function randomColoredCircle( canvas : Graphics ) : void&lt;br /&gt;{&lt;br /&gt; var color : uint = Math.round( Math.random() * 0xFFFFFF );&lt;br /&gt; var xPosition : Number = 0;&lt;br /&gt; var yPosition : Number = 0;&lt;br /&gt; var radius : Number = 30;&lt;br /&gt; &lt;br /&gt; canvas.beginFill( color );&lt;br /&gt; canvas.drawCircle( xPosition, yPosition, radius );&lt;br /&gt; canvas.graphics.endFill();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This works by having separate functions for Sprite and MovieClip objects. All those functions do is to extract Graphics objects from their owners and send the Graphics to another function, one that actually does the drawing. This works, because though MovieClips and Sprites are different classes, a Graphic is a Graphic is a Graphic. I can now easily draw on Shapes by making one more graphic-extraction function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function randomColoredCircleOnSHAPE( target : Shape ) : void &lt;br /&gt;{&lt;br /&gt; var canvas : Graphics = target.graphics;&lt;br /&gt; randomColoredCircle( canvas );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Though this approach moves in the right direction, we can do better. In an object-oriented system, if you want to do the same thing to two related classes, you do it to their parent class. In fact, both MovieClip and Sprite descend directly from DisplayObject. So, in theory, I should be able to elegantly solve my problem (and eliminate all the graphics-extractor classes) by drawing on DisplayObjects instead of MovieClips and Sprites:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function randomColoredCircle( target : DisplayObject ) : void &lt;br /&gt;{&lt;br /&gt; var color : uint = Math.round( Math.random() * 0xFFFFFF );&lt;br /&gt; var xPosition : Number = 0;&lt;br /&gt; var yPosition : Number = 0;&lt;br /&gt; var radius : Number = 30;&lt;br /&gt; &lt;br /&gt; target.graphics.beginFill( color );&lt;br /&gt; target.graphics.drawCircle( xPosition, yPosition, radius );&lt;br /&gt; target.graphics.endFill();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The variable target can accept any object in the DisplayObject family, so I can call this function as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var sprite : Sprite = new Sprite();&lt;br /&gt;var movieClip : MovieClip = new MovieClip();&lt;br /&gt;&lt;br /&gt;randomColoredCircle( sprite );&lt;br /&gt;randomColoredCircle( movieClip );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, this WON'T WORK. I'll get an error telling my that DisplayObjects don't have a property called "graphics." In fact, they don't. This is because though MovieClips, Shapes and Sprites have graphics properties, there are other DisplayObjects that don't. For instance, TextField is a DisplayObject descendant that doesn't have a graphics property. You can't draw on a TextField.&lt;br /&gt;&lt;br /&gt;The definition of DisplayObject looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class DisplayObject&lt;br /&gt;{&lt;br /&gt; private var _x : Number;&lt;br /&gt; private var _y : Number;&lt;br /&gt; ...&lt;br /&gt; //Note: no _graphics property! &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;MovieClip, Sprite and Shape extend DisplayObject like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MovieClip extends DisplayObject&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt; private var _graphics : Graphics;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;TextField extends it like this: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class TexTField extends DisplayObject&lt;br /&gt;{&lt;br /&gt; private var _embedFonts : Boolean;&lt;br /&gt; private var _text : String;&lt;br /&gt; ...&lt;br /&gt; //Note: no _graphics property! &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So though you can store both a Sprite and a MovieClip in a variable typed to DisplayObject, you can't access the graphics property of that variable, because DisplayObjects don't have graphics.&lt;br /&gt;&lt;br /&gt;However, since several of DisplayObject's children DO have graphics properties, you should be able to refer to all those children generically via a common interface. In other words, what Adobe SHOULD have done -- but didn't -- is to define an IDrawable interface like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IDrawable&lt;br /&gt;{&lt;br /&gt; //returns the private _graphics property&lt;br /&gt; function get graphics () : Graphics;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then, it should have implemented this interface for MovieClip, Sprite and Shape:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MovieClip extends DisplayObject implements IDrawable&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Sprite extends DisplayObject implements IDrawable&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Shape extends DisplayObject implements IDrawable&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Had Adobe just added that little bit of extra code, we could type variables as IDrawable and not have to worry about whether they were Sprites, MovieClips or Shapes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var sprite : IDrawable = new Sprite();&lt;br /&gt;var moveClip : IDrawable = new MovieClip();&lt;br /&gt;var shape : IDrawable = new Shape();&lt;br /&gt;&lt;br /&gt;randomColoredCircle( sprite );&lt;br /&gt;randomColoredCircle( movieClip );&lt;br /&gt;randomColoredCircle( shape );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The last step to making this work is to rewrite the randomColoredCircle function so that it accepts IDrawable objects:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function randomColoredCircle( target : IDrawable ) : void&lt;br /&gt;{&lt;br /&gt; var color : uint = Math.round( Math.random() * 0xFFFFFF );&lt;br /&gt; var xPosition : Number = 0;&lt;br /&gt; var yPosition : Number = 0;&lt;br /&gt; var radius : Number = 30;&lt;br /&gt; &lt;br /&gt; target.graphics.beginFill( color );&lt;br /&gt; target.graphics.drawCircle( xPosition, yPosition, radius );&lt;br /&gt; target.graphics.endFill();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This works because ALL IDrawable objects have a graphics property:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IDrawable&lt;br /&gt;{&lt;br /&gt; //returns the private _graphics property&lt;br /&gt; function get graphics () : Graphics;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Like I said, we COULD have used this method IF Adobe had just implemented a common interface for all the classes with graphics properties. They should have done this, as it's a standard and good programming technique, but they didn't. However, all is not lost, because we can do it ourselves by extending the MovieClip, Sprite and Shape classes and making sure our new classes implement IDrawable. &lt;br /&gt;&lt;br /&gt;Below, I'll show the complete code to do this. It's a small amount of code, involving some empty classes. The classes are empty because we don't want to add anything to them other than the fact that they implement IDrawable. In other words, MySprite is exactly the same as Sprite, except for the fact that MySprite implements IDrawable and Sprite doesn't:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.Graphics;&lt;br /&gt; &lt;br /&gt; public interface IDrawable&lt;br /&gt; {&lt;br /&gt;  function get graphics() : Graphics&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.Sprite;&lt;br /&gt; &lt;br /&gt; public class MySprite extends Sprite implements IDrawable&lt;br /&gt; {&lt;br /&gt; &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.MovieClip;&lt;br /&gt; &lt;br /&gt; public class MyMovieClip extends MovieClip implements IDrawable&lt;br /&gt; {&lt;br /&gt; &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt; import flash.display.Shape;&lt;br /&gt; &lt;br /&gt; public class MyShape extends Shape implements IDrawable&lt;br /&gt; {&lt;br /&gt; &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's it. Now I just need to use MyShape, MySprite and MyMovieClip instead of Shape, Sprite and MovieClip, and I'll be guaranteed that all of my classes will implement a common interface:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var sprite : MySprite = new MySprite();&lt;br /&gt;var movieClip : MyMovieClip = new MyMovieClip();&lt;br /&gt;var shape : MyShape = new MyShape();&lt;br /&gt;&lt;br /&gt;randomColoredCircle( sprite );&lt;br /&gt;randomColoredCircle( shape );&lt;br /&gt;randomColoredCircle( movieClip );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;MyShape, MySprite and MyMovieClip have all properties and methods of Shape, Sprite and MovieClip (width, rotation, etc.), because they inherit those properties from the classes they extend.&lt;br /&gt;&lt;br /&gt;Even if you don't ever need to treat Sprites, Shapes and MovieClips as if they are all the same type of objects, I hope my approach shows off the usefulness of common interfaces. If you have several classes that share similar traits, it's key that you relate those classes via inheritance and/or an interface. Doing so will make your code much more extendible for future projects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-6655308526956966539?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/6655308526956966539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/adobes-mistake-displayobjects-need.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6655308526956966539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6655308526956966539'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/adobes-mistake-displayobjects-need.html' title='adobe&apos;s mistake: displayObjects need interfaces'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-4903861977609887924</id><published>2009-08-02T13:04:00.000-07:00</published><updated>2009-08-02T13:57:22.568-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bezier corner round rounding rounded actionscript shape shapes'/><title type='text'>rounding cornders</title><content type='html'>Whenever possible, I draw with code instead of with Flash's drawing tools. I do this because (a) it allows me to make dynamic changes to shapes at run-time, and (b) because it keeps all the app-construction info in one place (in the code), not split between the code and the stage or library.&lt;br /&gt;&lt;br /&gt;But I keep needing shapes with rounded corners. Actionscript has a built-in rounded-corner rectangle class (graphics.drawRoundedRect), but that's the only rounded-cornder method available. I often need rounded-corner triangles, rounded-corner tooltips and rounded-corner circles (just kidding on that last one). So I decided to create a method that allowed me to round the corners of any shape. &lt;br /&gt;&lt;br /&gt;I knew I'd need math, which is not my strong point. So I ignored that problem and focused on how I'd create rounded corners with a Bezier-pen tool. Think of the top of a triangle: imaging making points on both of the lines that meet at the top (the apex). If those points are down a little from the top, they can act as start and end points for a Bezier curve. In the illustration, below, I've drawn the start and end points as red dots.&lt;br /&gt;&lt;br /&gt;A point at the apex (blue dot) can act as a control point, giving you all the points you need to draw a curve:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/RoundedShapesPics/topOfTriangle.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Note: Actionscript's Bezier curves have just one control point. The curve is the widest-possible path that Flash can draw without it crossing outside the triangle formed by the start, end and control points.&lt;br /&gt;&lt;br /&gt;With this approach, I could make a rounded-cornered shape by starting with a straight-cornered shape and calculating a Bezier curve for each corner.&lt;br /&gt;&lt;br /&gt;The first step would be to figure out how to plot points that are a little ways in from the ends of all the lines, as shown by the red dots, above. Generalizing this, I needed a way to find a point on a line. Which is where math reared its ugly head. Luckily, google exists for moments like this. Before long, I found a formula and turned it into a nifty function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function pointOnLine(t : Number, point1 : Point, point2 : Point ) : Point&lt;br /&gt;{&lt;br /&gt; var xResult : Number = point1.x + ( t * ( point2.x - point1.x ) );&lt;br /&gt; var yResult : Number = point1.y + ( t * ( point2.y - point1.y ) );&lt;br /&gt; return new Point( xResult, yResult );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can use this function by first creating two points that make up a line...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import flash.geom.Point;&lt;br /&gt;&lt;br /&gt;var start : Point = new Point( 100, 100 );&lt;br /&gt;var end : Point = new Point( 100, 500 );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... and then handing the points to the pointOnLine function. You also have to hand it t, which is a number between 0 and 1. A t of zero returns the start-point of the line; a t of .5 returns the mid-point of the line. A t of 1 returns the end-point of the line. And so on. So to get a point close to the end of the line, I could call the function like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var nearEnd : Point = pointOnLine( .8, start, end );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That out of the way, I could now calculate all the start and end points I needed by calling pointOnLine() twice for each line in my shape, e.g. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//note that I'm using .2 and .8 for t&lt;br /&gt;var nearStart : Point = pointOnLine( .2, start, end );&lt;br /&gt;var nearEnd : Point = pointOnLine( .8, start, end );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's an illustration of nearStart and nearEnd for one lines on a triangle:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/RoundedShapesPics/twoPoints.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Now all I had to do was to loop through all the lines on the triangle to find the rest of the start and end points:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/RoundedShapesPics/allPoints.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;After that, it was easy to find the corner points, since they were used to define the triangle in the first place:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/RoundedShapesPics/cornerPoints.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;I then drew curves through each group of start-end-corner points with the built in curve-to function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;graphics.moveTo( start.x, start.y );&lt;br /&gt;graphics.curveTo( control.x, control.y, end.x, end.y );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/RoundedShapesPics/curvesAdded.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;In the illustrations here, I've drawn the triangle so you can understand my thought process. In fact, my code never draws the straight-edge version. If it did, it would have to go back later and erase the non-curvy corners. Instead, it draws actual lines from the two inset points of each virtual line: e.g. lines from the .2 t to the .8 t of each line.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/RoundedShapesPics/cornersErased.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;If I go through the same process with the t values adjusted to move the pointOnLines in a little, say .4 and .6, I get something like this:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/RoundedShapesPics/pointsMovedIn.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;I packaged up my code in a utility class called RoundedShapes. To use it, you call its draw() method as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;RounedShapes.draw( target, roundness, points );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;target&lt;/span&gt; parameter is the display object on which you want to draw. It can be any object with a graphics property: e.g. Sprite, MovieClip or Shape.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;roundness&lt;/span&gt; parameter is essentially t. Roundness must be a number between 0 and 1, 0 being the same as straight.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;points&lt;/span&gt; parameter is an array of Points, defining the straight-corner version of the shape.&lt;br /&gt;&lt;br /&gt;To draw a rounded-corner triangle, you could use code like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import com.grumblebee.ui.drawing.RoundedShapes;&lt;br /&gt;&lt;br /&gt;var sprite : Sprite = new Sprite();&lt;br /&gt;var points : Array = [ new Point( 320, 10 ),&lt;br /&gt;   new Point( 420, 80 ),&lt;br /&gt;   new Point( 320, 160 ),&lt;br /&gt;   new Point( 320, 10 ) ];&lt;br /&gt;&lt;br /&gt;var roundness : Number = .2;&lt;br /&gt;&lt;br /&gt;sprite.graphics.lineStyle( 2, 0x000000 );&lt;br /&gt;sprite.graphics.beginFill( 0xFF0000 );&lt;br /&gt;RoundedShapes.draw( sprite, roundness, points );&lt;br /&gt;sprite.graphics.endFill();&lt;br /&gt;addChild( sprite );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's a swf with some example shapes drawn by RoundedShapes.draw(). Just for fun, I animated the roundness parameter of the star:&lt;br /&gt;&lt;br /&gt;&lt;object width="450" height="300"&gt;&lt;br /&gt;&lt;param value="http://www.grumblebee.com/grumblecode/RoundedShapes.swf" name="movie"/&gt;&lt;br /&gt;&lt;embed width="450" src="http://www.grumblebee.com/grumblecode/RoundedShapes.swf" height="300"&gt;&lt;br /&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Here's &lt;a href="http://www.grumblebee.com/grumblecode/RoundedShapes.zip"&gt;a link to the RoundedShapes class and an example fla&lt;/a&gt;. Happy rounding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-4903861977609887924?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/4903861977609887924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/rounding-cornders.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4903861977609887924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4903861977609887924'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/rounding-cornders.html' title='rounding cornders'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-1663370768151259394</id><published>2009-08-01T14:03:00.000-07:00</published><updated>2009-08-01T14:08:32.390-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interface actionscript oop'/><title type='text'>the beauty of interfaces</title><content type='html'>&lt;span style="font-weight:bold;"&gt;= my humble origins =&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;For my first few years as a programmer, I had a hard time understanding interfaces.&lt;br /&gt;&lt;br /&gt;Before continuing, let me explain what I mean by "interfaces," since people use the word in several ways. I'm not talking about user interfaces (buttons and the like). I always understood those. I'm talking about formal interfaces in Actionscript (and similar structures in other languages), the kind you define like this:&lt;br /&gt;&lt;br /&gt;public interface MyInterface {}&lt;br /&gt;&lt;br /&gt;I understood how to define an interface. That's easy, as I showed above. And I understood how to use one:&lt;br /&gt;&lt;br /&gt;public class MyClass implements MyInterface {}&lt;br /&gt;&lt;br /&gt;What I didn't understand was the point of interfaces. So I just never used them, and my programs seemed to work. So I couldn't see what interfaces would add to the mix.&lt;br /&gt;&lt;br /&gt;Every once in a while, I heard sayings like, "Program to an interface, not to an implementation," and I'd just shrug and move on. (Actually, that saying really confused me. I couldn't get past "Program to". What did it mean to "program to" something? I understood "program for," as in "program for money" and "program by," as in "program by starting with small methods first," but what on Earth did "program to" mean?)&lt;br /&gt;&lt;br /&gt;When I read programming books, they rarely seemed to be written for me. Like most Actionscript developers, I had worked my way up to programming via design and animation. Most of my projects were small and didn't involve a team. But the books I read were constantly talking about large-scale applications and the need to clarify your code so that other team-members could understand it. "Don't name a variable 'a'," those books told me, because 'no one will understand what that means.'" That didn't really resonate with me, because as the lone programmer on small projects, I could easily remember what my variables meant, even if I gave them cryptic names. &lt;br /&gt;&lt;br /&gt;What no one told me is that small-time programmers gradually morph into big-time programmers. Before I knew it, my bosses and clients were asking me to add many new features to my programs, and those programs started to grow larger and larger. I found myself writing dozens of lines of code, then hundreds, then thousands... This change happened so gradually that I didn't notice it until I was knee deep in variables named "a," "foo" and "a2".&lt;br /&gt;&lt;br /&gt;By the sixth week of a project, I couldn't understand what I had coded on the first week. Worse, sometimes my clients would ask me to add features to a project I'd shelved a year ago. When I dusted it off and looked at the code, it seemed to be written in Swahili. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;= I am a team of one =&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;One day it dawned on me that I DID work on a team! My team was comprised of me last week, me last year, me yesterday, me today and me two months from now. And I'd get really pissed off at the me from last week if he didn't leave the code-base tidy, so that the me from this week could easily navigate through it. Many coders do, in fact, work on teams of multiple people. Most of the time, I still work alone. But I've come to realize this doesn't matter. It's just as important for me to write clean code for myself as it is for someone at Microsoft or Adobe to write clean code for their co-workers.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;= what is clean code? =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"Writing clean code" means at least two things:&lt;br /&gt;&lt;br /&gt;1. Writing code that rarely has to be examined.&lt;br /&gt;2. Writing code that, if it DOES have to be examined, is easy to understand.&lt;br /&gt;&lt;br /&gt;Point one means that coding is a form of organized forgetting. If it takes me five hours to write a complex sort routine, I don't ever want to have to look at its guts again. So I make sure it works and then stuff it in a function called sort(). That name is the only part of the routine that the future me should need to worry about. As far as he's concerned, the function looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function sort( array : Array ) : Array&lt;br /&gt;{&lt;br /&gt; blah blah blah (it just works...)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But, because it's impossible to predict the future, there's a chance that the me of tomorrow might have to dig into the sort()'s guts. So I owe it to him to make the actual steps of the routine clear, too. That's the second point, above.&lt;br /&gt;&lt;br /&gt;Sometimes I morbidly think of programming as if I'm making my will. I don't want my loved ones to be bothered by it while I'm alive. I just want them to know it exists. When I die, I want it to be easy to execute without anyone having to go through a lot of legal hassle. But if, for some reason, someone absolutely needs to examine it under a microscope, I want them to see that my will is well ordered, all i's dotted; all t's crossed.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;= what is a programmer's job? =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Even when I first realized the import of clean code, I thought a programmer's job was to first make sure his program worked and only second to make sure it was easy to read. Over time, I realized that the opposite is true. My programs should first and foremost be easy for humans (including me next month) to read. Why? Because I'm inevitably going to spend more time debugging my programs than I spent writing them, and debugging is horrible (and costly in terms of man-hours) if the code is messy. Yes, it's important that a program works. But if the code is clean, it should be relatively easy to get it working if it's broken. But if the code is messy, it's hard to keep it from breaking and nearly impossible to fix it when it does break. &lt;br /&gt;&lt;br /&gt;Have you ever had the horrible experience of fixing a bug and then finding that your fix caused another bug? And then fixing THAT bug and discovering that your second fix caused a worse bug? That's the horror of messy code. That doesn't happen with clean code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= what does clean code look like? =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Clean code looks like anything else that's clean and organized:&lt;br /&gt;&lt;br /&gt;"A place for everything and everything in its place."&lt;br /&gt;&lt;br /&gt;This means making clear separations between parts: it means that you shouldn't write a class called GameAndHighScoreManager. You should write one class called GameManager and another called HighScoreManager; it means that you shouldn't write a function called moveCowboysAndIndians(); you should write one function called moveCowboys() and another called moveIndians().&lt;br /&gt;&lt;br /&gt;And it means that you should separate interfaces from the implementations. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;== what is an iterface? ==&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An interface is the public parts of a class. It allows other classes to interact with that class. If there's a class called Human and a class called Dog, what parts of Dog does Human need to know about? (What parts of Dog do I have to think about while I'm programming Human? What parts of Dog can I forget about?) Human needs to feedDog(); he needs to walkDog(); he needs to know isDogAsleep(). However, he doesn't need to digestDogsFood() or makeDogsHeartBeat().&lt;br /&gt;&lt;br /&gt;Class definitions give us an easy way to make some methods accessible while keeping others private, as I do here:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Dog&lt;br /&gt;{&lt;br /&gt; public function feed( food : Food ) : void { ... }&lt;br /&gt; &lt;br /&gt; private function digest() : void { ... }&lt;br /&gt; &lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem with this is that I haven't separated my interface from its implementation. It's like a car that you have to drive by fiddling directly with the parts under the hood. Making some of those parts private is a good idea. But it's a bad idea to make other parts public by cutting strategic holes in the hood. Rather, a car should have an interface that's completely separate from its implementation. In fact, cars do. In a car, these interfaces are called dashboards. If you open a car's hood, you don't see little labels that say "public" and &lt;br /&gt;private." Everything under the hood is private. Unless you're an expert, you should only be operating a car via its interface: the dashboard.&lt;br /&gt;&lt;br /&gt;Alas, in the case of Dog, both interface and implementation are in the guts of the class. This can lead to some very confusing problems. For instance, let's say my Human class winds up feeding his dog:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Human&lt;br /&gt;{&lt;br /&gt; public function feedDog( dog : Dog ) : void&lt;br /&gt; {&lt;br /&gt;  var kibbles : Food = new Food( "kibbles" );&lt;br /&gt;  dog.feed( kibbles );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Everything should work fine unless some idiot -- e.g. the future me -- starts screwing around inside the Dog class.&lt;br /&gt;&lt;br /&gt;Well, actually there's a lot I can do inside that class without causing a problem. For instance, I can change...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function feed( food : Food ) : void&lt;br /&gt;{&lt;br /&gt; yum yum yum...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;to...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function feed( food : Food ) : void&lt;br /&gt;{&lt;br /&gt; yuck yuck yuck...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Because Human doesn't care about the innards of feed(). All Human cares about is calling the method. Once called, it's free to like or dislike it's food, without affecting Human.&lt;br /&gt;&lt;br /&gt;But what if I change food's parameters? &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function feed( foodType : String, calories : int ) : void&lt;br /&gt;{&lt;br /&gt; blah blah blah...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I've now broken Human:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Human&lt;br /&gt;{&lt;br /&gt; public function feedDog( dog : Dog ) : void&lt;br /&gt; {&lt;br /&gt;  var kibbles : Food = new Food( "kibbles" ); //this no longer works&lt;br /&gt;  dog.feed( kibbles );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I could also break Human by renaming Dog's feed method to chew() or bite().&lt;br /&gt;&lt;br /&gt;If you take your car in to be repaired, you probably won't be upset if the mechanic changes things around under the hood, as long as your car works when you get it back. You won't even know what changes he made. However, if he messes with the interface -- if he removes the steering wheel and sticks the break pedal in the glove compartment -- you'll be confused and angry. Similarly, Human has a right to be angry, because Dog has changed his interface. But I can't really blame Dog. After all, his interface is inside him. It's not really an interface, it's just part of his implementation that's been labeled public. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;= making a formal interface =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So how do we give Dog an real, dashboard-like interface? In Actionscript, we do it like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt; public interface IDog&lt;br /&gt; {&lt;br /&gt;  function feed( food : Food ) : void;&lt;br /&gt;  function walk() : void&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;By convention, interface names begin with a capital I. Inside the body of an interface, you list the signature of each public function (e.g. all the items on the dashboard). You don't label them "public," because everything in the interface is public -- that's the whole point of an interface. You don't list the body of the functions, because bodies are filled with implementation details. Implementation details do not belong on interfaces. &lt;br /&gt;&lt;br /&gt;Now, I can tie my Dog class to this interface as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Dog implements IDog { ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Anyone who wants to use my Dog class shouldn't bother looking at it's source code. Instead, they should look at its interface. It's interface contains everything users need to know. Dog itself is just a confusion of details. Users should...&lt;br /&gt;&lt;br /&gt;... program to the interface, not the implementation!&lt;br /&gt;&lt;br /&gt;By saying that Dog "implements IDog," that class is making a promise. It's promising to conform to the rules of IDog. It's saying, "Regardless of how I digest my food and whether or not I like it, you'll always be able to feed me via my feed method. I reserve the right to change how feed is implemented at any time, but I won't change the method name, the parameters it takes in, or what it returns. And, as a user, that's all you should care about."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= an interface is a promise = &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I remember when I first read that an interface is "a kind of promise." I was confused. What happens if I break the promise? If it's just a promise, can't I just promise not to change method names or alter their kind and number of parameters? Sure, I can, but there's nothing to stop me if I break my promise. On the other hand, if I type in my code that Dog "implements IDog," I'll get a compile error if I don't keep my promise. For example, if I change Dog's feed method to this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function feed( foodType : String, calories : int ) : void&lt;br /&gt;{&lt;br /&gt; blah blah blah...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My code won't compile, because IDog says it should look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function feed( foodType : String, calories : int ) : void&lt;br /&gt;{&lt;br /&gt; function feed( food : Food ) : void;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And, in a good IDE (e.g. Flex Builder -- a.k.a. Flash Builder -- or FDT), I won't have to wait until compile time. Most IDEs tell you if you're not following an interface as you type your code.&lt;br /&gt;&lt;br /&gt;So a real nuts-and-bolts reason to use interfaces is that they catch errors before the errors happen!&lt;br /&gt;&lt;br /&gt;By the way, this doesn't mean that I can't change interfaces. I can. If I want to change the feed() method, I can go into IDog and redefine it. As with all aspects of code, interfaces evolve over time. The good news is that when you make changes to an interface, you get advanced warning about problems you might be causing. You can fix those problems before they rear their heads.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= advanced interface tricks =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once you get the hang of interfaces, there are some useful advanced features worth using. For instance, interfaces can inherit from other interfaces:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IMachine&lt;br /&gt;{&lt;br /&gt; function turnOn() : void;&lt;br /&gt; function turnOff() : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface ITransporter extends IMachine&lt;br /&gt;{&lt;br /&gt;  function beamUp( person : Person ) : void;&lt;br /&gt; function beamDown( person: Person ) : void;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And classes can implement multiple interfaces:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IKillable&lt;br /&gt;{&lt;br /&gt; function stabMe() : void;&lt;br /&gt; function shootMe() : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface ITameable&lt;br /&gt;{&lt;br /&gt; function petMe() : void;&lt;br /&gt; function feedMe() : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Shark extends Creature implements IKillable { ... }&lt;br /&gt;public class Demon extends SupernaturalBeing implements ITamebale { ... }&lt;br /&gt;public class Wolf extends Creature implents IKillable, ITameable { ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note: it's another convention it name intefances I-something-able.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= interfaces can be used as types =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Coolest of all, you can type variables to interfaces instead of implementations. For instance "var dog : IDog" instead of "var dog : Dog". Here's a more complete example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IOpenable&lt;br /&gt;{&lt;br /&gt; function open() : void&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Box implements IOpenable&lt;br /&gt;{&lt;br /&gt; public function open() : void { trace( "There's money inside!!!" ); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Skull implements IOpenable&lt;br /&gt;{&lt;br /&gt; public function open() : void { trace( "There's a brain inside!!!" ); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Door implements IOpenable&lt;br /&gt;{&lt;br /&gt; public function open() : void { trace( "Nothing to fear. Come on in!" ); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class DocumentClass&lt;br /&gt;{&lt;br /&gt; //notice how I typed the variable aThing&lt;br /&gt; private function openAThing( aThing : IOpenable) : void&lt;br /&gt; {&lt;br /&gt;  aThing.open();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //constructor&lt;br /&gt; public function DocumentClass() &lt;br /&gt; {&lt;br /&gt;  var box : Box = new Box();&lt;br /&gt;  var skull : Skull = new Skull();&lt;br /&gt;  var door : Door = new Door();&lt;br /&gt;  &lt;br /&gt;  openAThing( box ); //There's money inside!!!&lt;br /&gt;  openAThing( skull ); //There's a brain inside!!!&lt;br /&gt;  openAThing( door ); //Nothing to fear. Come on in!&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The magic here is that box, skull and door are three totally unrelated classes. They aren't children of the same base class. But they all share the same interface. So as long as you type a variable to IOpenable, that variable can store any of those classes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= start your projects with interfaces =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Creating interfaces is a great way to start a project (you'll refine those interfaces as you go). If all you have at the beginning is interfaces, what else can you do except "program to interfaces"? &lt;br /&gt;&lt;br /&gt;A great way to think about an Object Oriented system is as a bunch of things all talking to each other, pushing each other, pulling each other, etc. As such, each of these things can only interact with another thing through its interface. So you don't need to know anything about implementation details in order to describe the whole system. You just need to know the public face of each thing.&lt;br /&gt;&lt;br /&gt;As an example, lets say that I'm making a Pacman game. I know nothing (yet) about how the objects will work, but I know that I'll need a maze, some dots (for the Pacman to eat), a Pacman and some ghosts to chase him and be chased by him. (To keep this example simple, I'll ignore other details, such as scores, lives and levels).&lt;br /&gt;&lt;br /&gt;Opening my editor, I'll make a first draft at the interfaces:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IPackman&lt;br /&gt;{&lt;br /&gt; function move( direction : String ) : void;&lt;br /&gt; function eatDot() : void;&lt;br /&gt; function eatGhost() : void;&lt;br /&gt; function render() : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface IGhost&lt;br /&gt;{&lt;br /&gt; function move( direction : String ) : void;&lt;br /&gt; function eatPackman() : void;&lt;br /&gt; function avoidPackman() : void;&lt;br /&gt; function returnToBase() : void;&lt;br /&gt; function render() : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface IMaze&lt;br /&gt;{&lt;br /&gt; function render() : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface IDot&lt;br /&gt;{&lt;br /&gt; function render() : void;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;== draft two ==&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Looking over my initial draft, I notice that both Packmen and Ghosts can move and eat. And everything seems to be renderable, which makes sense in a visual system. So I redraft my interfaces to group similar methods together:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IRenderable&lt;br /&gt;{&lt;br /&gt; function render() : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface IMovable&lt;br /&gt;{&lt;br /&gt; function move( direction : String ) : void;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface IEater&lt;br /&gt;{&lt;br /&gt; function eat( food : IEdibleObject ) : void;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;When I later define my classes, they will all implement IRenderable. Packman and Ghost will both implement IMovable and IEater.&lt;br /&gt;&lt;br /&gt;Notice the reference to IEdibleObject inside IEater's eat method. I need to define that, too:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IEdibleObject&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= empty interfaces =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sometimes I create empty interfaces. At this point in development, all I know is that a bunch of different kinds of things -- packmen, ghosts and dots -- are all edible. I'm not sure if editable object will need to implement any common methods. And maybe they should all be descended from a base class instead of (or in addition to) implementing a common interface. But at this point, the empty interface serves to remind me that this is a sensible way to group certain objects. If I later decide to add a digestMe() method inside IEdibleObject, my IDE will remind me that I need to implement in this in all classes that are implementing it.&lt;br /&gt;&lt;br /&gt;To wrap thing up (for now), I'll add the following definitions to my list of interfaces, though I expect I'll make more drafts when I start working on implementation:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IEnemy&lt;br /&gt;{&lt;br /&gt; function returnToBase() : void;&lt;br /&gt; function avoid( target : IGamepiece ) : void&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//for dots, packmen, ghosts, etc. Do I need this AND IEdible?&lt;br /&gt;public interface IGamepiece&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= interfaces and class inheritance =&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Sometimes I wind up using both interfaces and class inheritance. This happens when I want a whole family of classes to implement an interface in the same way:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//this class will never be instantiated as an object, &lt;br /&gt;//which is why I have named it starting with the prefix "Abstract"&lt;br /&gt;public class AbstractCreature implements IMoveable, IRenderable, IGamepiece&lt;br /&gt;{&lt;br /&gt; public static var STEP : int = 50;&lt;br /&gt;&lt;br /&gt; //IRenderable forces me to include this method&lt;br /&gt; public function render() : void&lt;br /&gt; {&lt;br /&gt;  //override in subclasses&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //IMovable forces me to include this method&lt;br /&gt; public function move( direction : String ) : void&lt;br /&gt; {&lt;br /&gt;  if ( direction == "up" ) this.y += STEP;&lt;br /&gt;  else if ( direction == "down" ) this.y -= STEP;&lt;br /&gt;  else if ( direction == "left" ) this.x -= STEP;&lt;br /&gt;  else if ( direction == "right" ) this.x += STEP;&lt;br /&gt;  //note: I'm not suggesting that this is how you'd&lt;br /&gt;  //animate a packman or ghost in real life.&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Packman extends AbstractCreature&lt;br /&gt;{&lt;br /&gt; override public function render() : void&lt;br /&gt; {&lt;br /&gt;  drawCircle();&lt;br /&gt;  cutPieSliceOutOfCircle();&lt;br /&gt;  animateMouthOpeningAndClosing();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function drawCircle() { ... };&lt;br /&gt; private function cutPieSliceOutOfCirce{ ... };&lt;br /&gt; privare function animateMouthOpeningAndClosing{ ... };&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Ghost extends AbstractCreature&lt;br /&gt;{&lt;br /&gt; override public function render() : void&lt;br /&gt; {&lt;br /&gt;  drawBody();&lt;br /&gt;  drawEyes();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function drawBody() { ... };&lt;br /&gt; private function drawEyes() { ... };&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I don't have to explicitly state that Packman and Ghost extend the interfaces IMovable and IRenderable, because they inherit that fact from their parent, AbstractCreature. All these classes also implement my empty (for now) IGamepiece interface -- just in case! &lt;br /&gt;&lt;br /&gt;Note that the subclasses are free to implement additional interfaces that aren't implemented by AbstractCreature. For instance, if I have an interface called IPlayerCharacter (for the character played by the actual player of the game, as opposed to the AI ghosts), I could have my Packman subclass extend that.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;= interfaces, me and Tim =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My relationship with interfaces has gone through three stages: at first I was baffled by them, then I got into them, and now I'm REALLY into them. For my third and current phase ("REALLY into them"), I have my friend &lt;a href="http://www.tcoz.com/blogger/blogger.html"&gt;Tim&lt;/a&gt; to thank. Tim, a seasoned programmer who has worked for Microsoft and programmed in many languages, makes interfaces for (almost) all his classes. Though I loved interfaces before I started talking to Tim about them, my immediate reaction to Tim's process was that he was taking a good thing too far. But the more I thought about it, the more I was unable to come up with an objection to Tim's way of working. If a class doesn't have a formal interface, then all its public methods are mashing up their interfaces with their implementations. That's messy and dangerous. So now I'm born again into the church of Tim.&lt;br /&gt;&lt;br /&gt;Tim's idea is a bit revolutionary in Actionscript circles, but it's the norm in some other programming communities and languages. For instance, in Objective-C (a suddenly popular language, since one must use for iPhone development), all classes must have separate interface files. Unfortunately, since Actionscript doesn't force you to use interfaces, many of developers don't bother.&lt;br /&gt;&lt;br /&gt;Not every one of my classes (or Tim's) implements an interface unique to itself. In many cases, large groups of classes all implement a single interface. Interfaces are, among other things, a great way of finding and expressing commonality. "I didn't think these classes had anything in common, but now I can see that they all render graphics. I'm going to make an interface called IRenderable and make them all implement it. Later, I can make a grand render-function that takes an array of IRenderable objects, loops through them and calls each of their render() methods!"&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;= when not to use interfaces =&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Like Tim, I don't bother making interfaces for Value-Object classes (a.k.a Data Transfer Objects). If a class is just a collection of public properties...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class ContactVO&lt;br /&gt;{&lt;br /&gt; public firstName : String;&lt;br /&gt; public lastName : String;&lt;br /&gt; public email : String;&lt;br /&gt; pubic phone : String;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... then there's not much of point to making an interface for it. I also don't make interfaces for utility classes, which are generally collections of static methods. I don't really think of such classes as classes. In their cases, "class" is just a cheap and easy way to group together a library of helper functions. &lt;br /&gt;&lt;br /&gt;But if something is an object that relates to other objects, it needs an interface. And since virtually everything in an OOP world is an object that relates to other objects, virtually everything in that world should have an interface.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-1663370768151259394?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/1663370768151259394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/08/beauty-of-interfaces.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1663370768151259394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1663370768151259394'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/08/beauty-of-interfaces.html' title='the beauty of interfaces'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2229392687786064775</id><published>2009-07-24T13:54:00.000-07:00</published><updated>2009-07-24T14:02:00.582-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='refactoring actionscript'/><title type='text'>a little lesson in refactoring</title><content type='html'>Here's a secret you already know: great writers revise. I learned more about writing by looking at an &lt;a href="http://www.orwelltoday.com/manuscript1984.shtml"&gt;early draft&lt;/a&gt; of George Orwell's "1984" than I did in any writing class. Orwell's prose seems so effortless. Yet its simplicity belies all the sweat he poured into it. Every page of his draft is riddled with multiple edits, cross-outs and revisions.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.grumblebee.com/grumblecode/images/1984.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Here's a secret you may not know: good programmers revise. When they get their program working, they know they've only begun their labor. The program is finished when it's easy for humans to read.&lt;br /&gt;&lt;br /&gt;Since I learned so much from looking over Orwell's shoulder, I wish I could do the same with lots of programmers, watching them refactor their work to make it clear. &lt;br /&gt;&lt;br /&gt;Unfortunately, most programming books omit this step. They either show you rough code that cries out for refactoring. Or they show you clean code that looks like it sprung into existence that way. &lt;br /&gt;&lt;br /&gt;When I first started programming, I wondered why my code never looked as good as examples in books. What I didn't realize is that the book examples were the end result of a hidden process, one that involved many drafts and revisions.&lt;br /&gt;&lt;br /&gt;So that you don't suffer the same confusion I did, I'm going to show you my revision process, starting with some very rough code I actually wrote. If you enjoy this process and want to learn more, I recommend the following books:&lt;br /&gt;&lt;br /&gt;- "&lt;a href=http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?ie=UTF8&amp;qid=1248461878&amp;sr=8-1&gt;Clean Code&lt;/a&gt;" by Robert C. Martin.&lt;br /&gt;&lt;br /&gt;- "&lt;a href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672/ref=sr_1_1?ie=UTF8&amp;qid=1248461986&amp;sr=8-1"&gt;Refactoring&lt;/a&gt;" by Martin Fowler and others.&lt;br /&gt;&lt;br /&gt;- "&lt;a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=sr_1_1?ie=UTF8&amp;qid=1248462051&amp;sr=8-1"&gt;Code Complete&lt;/a&gt;" by Steve McConnell.&lt;br /&gt;&lt;br /&gt;I'm not going to demo a complex piece of code. I'm going to show you the sort of thing you've probably written a hundred times: code to draw a rectangle. &lt;br /&gt;&lt;br /&gt;Going into my project, I knew I'd have to draw a bunch of rectangles for various background elements and buttons. I knew that some of them would have both fills and strokes, others would have just fills, and still others would have just strokes. The ones with strokes would have various stroke widths. &lt;br /&gt;&lt;br /&gt;I decided to make a CustomRectangle class that allowed for all of these variations. Here's my first attempt at the class header and its constructor:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import flash.display.Sprite;&lt;br /&gt;import com.grumblebee.enums.Colors;&lt;br /&gt;&lt;br /&gt;public class CustomRectangle extends Sprite&lt;br /&gt;{&lt;br /&gt; private var _displayWidth : Number;&lt;br /&gt; private var _displayHeight : Number;&lt;br /&gt; private var _fillColor : uint;&lt;br /&gt; private var _strokeColor : uint;&lt;br /&gt; private var _strokeWidth : Number;&lt;br /&gt;&lt;br /&gt; public function CustomRectangle( displayWidth : Number = 0,&lt;br /&gt;          displayHeight : Number = 0,&lt;br /&gt;          fillColor : uint = Colors.NO_COLOR,&lt;br /&gt;          strokeColor : uint = Colors.NO_COLOR&lt;br /&gt;          strokeWidth : Number = 1 )&lt;br /&gt; {&lt;br /&gt;  _displayWidth = displayWidth;&lt;br /&gt;  _displayHeight = displayHeight;&lt;br /&gt;  _fillColor = fillColor;&lt;br /&gt;  _strokeColor = strokeColor;&lt;br /&gt;  _strokeWidth = strokeWidth;&lt;br /&gt; &lt;br /&gt;  render();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function render() { ... }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You may be wondering about Colors.NO_COLOR. Since I'm using uints to store colors, I need a way to un-set a color value. ints and uints default to zero, and in the hex-color system, zero is black (0x000000). ints and uints can't be set to undefined or null, so where does that leave me? How can I say "there's no fill color?" &lt;br /&gt;&lt;br /&gt;It leaves me with uint.MAX_VALUE. uint.MAX_VALUE is a built-in constant that holds the largest number your system can store in a unit (int has both MAX_VALUE and MIN_VALUE constants). &lt;br /&gt;&lt;br /&gt;MAX_VALUE might resolve to a different number on different OSes.  Out of curiosity, I decided to trace( uint.MAX_VALUE ) on my Mac. As it happens, my Mac's MAX_VALUE for uints is 4,294,967,295. That's way larger than the largest color-value, which is 0xFFFFFF or 16,777,215. (Though it's NOT larger than 0xFFFFFFFF, so if you're using alpha+color hex numbers, you need a different solution!)&lt;br /&gt;&lt;br /&gt;So I decided that a "color value" of uint.MAX_VALUE equals no color. To make my code a bit more readable, I created an enum class for colors:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Colors&lt;br /&gt;{&lt;br /&gt; public static const NO_COLOR : uint = uint.MAX_VALUE;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Getting back to my CustomRectangle class, I now needed to define the render method: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function render() : void&lt;br /&gt;{&lt;br /&gt; if ( _strokeColor != Colors.NO_COLOR &amp;&amp; _fillColor != Colors.NO_COLOR )&lt;br /&gt; {&lt;br /&gt;  if ( _strokeColor != Colors.NO_COLOR ) &lt;br /&gt;   graphics.lineStyle( _strokeWidth, _strokeColor );&lt;br /&gt;   &lt;br /&gt;  if ( _fillColor != Colors.NO_COLOR )&lt;br /&gt;   graphics.beginFill( _fillColor );&lt;br /&gt;   &lt;br /&gt;  graphics.drawRect( 0, 0, _displayWidth, _displayHeight );&lt;br /&gt;  graphics.endFill();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's not terrible code by any means, but it doesn't pass the Headache Test (HT). To give your code the HT, unfocus your eyes slightly and look at it. If you see a mess of stuff in parenthesis and multiple levels of nesting, your code fails the HT. Don't feel bad. Most first-draft code fails.&lt;br /&gt;&lt;br /&gt;My code is not all that hard to figure out. But a future reader (e.g. me next week) doesn't want to waste his time trying to figure it out. He wants to just look at it and GET it! So let's help him out.&lt;br /&gt;&lt;br /&gt;First, let's rector the outer-most conditional. Any time you see &amp;&amp; or ||, a refactoring bell should go off in your head. Why? Because multiple conditions are headache inducing. They are even that way in English. Compare...&lt;br /&gt;&lt;br /&gt;"I'll take you to the zoo if it's not raining tomorrow and if the temperature is above 50 degrees."&lt;br /&gt;&lt;br /&gt;... with ...&lt;br /&gt;&lt;br /&gt;"I'll take you to the zoo tomorrow if it's a nice day."&lt;br /&gt;&lt;br /&gt;Along these lines, we'll refactor the code as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function render() : void&lt;br /&gt;{&lt;br /&gt; if ( isRenderable() )&lt;br /&gt; {&lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And we'll move the ugly conditional into it's own helper method:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function isRenderable() : Boolean&lt;br /&gt;{&lt;br /&gt; if ( _strokeColor != Colors.NO_COLOR &amp;&amp; _fillColor != Colors.NO_COLOR )&lt;br /&gt;     return true;&lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In case you didn't know, you don't have to wrap the second return statement in an else clause. Return statements always cause their methods to end immediately, so if the "return true" executes, the "return false" will never run. &lt;br /&gt;&lt;br /&gt;You might argue that we didn't really simplify the compound-if statement. We just moved it. I agree, and sometimes that's the best you can do. At least we've burried the ugly code. Readers who don't want a headache can just read as far as the call to isRenderable(). &lt;br /&gt;&lt;br /&gt;But we can do better: let's refactor the two clauses of the compound if into two separate methods:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function isRenderable() : Boolean&lt;br /&gt;{&lt;br /&gt; if ( hasStroke() || hasFill() ) return true;&lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function hasStroke() : Boolean&lt;br /&gt;{&lt;br /&gt; if ( _strokeColor != Colors.NO_COLOR ) return true;&lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function hasFill() : Boolean&lt;br /&gt;{&lt;br /&gt; if ( _fillColor != Colors.NO_COLOR ) return true;&lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Though we just wrote hasFill() and hasStroke() to simplify the isRenderable() method, it now looks like they can do double-duty and also help us simplify render(). Let's change this...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function render() : void&lt;br /&gt;{&lt;br /&gt; if ( isRenderable() )&lt;br /&gt; {&lt;br /&gt;  if ( _strokeColor != Colors.NO_COLOR ) &lt;br /&gt;   graphics.lineStyle( _strokeWidth, _strokeColor );&lt;br /&gt;   &lt;br /&gt;  if ( _fillColor != Colors.NO_COLOR )&lt;br /&gt;   graphics.beginFill( _fillColor );&lt;br /&gt;   &lt;br /&gt;  graphics.drawRect( 0, 0, _displayWidth, _displayHeight );&lt;br /&gt;  graphics.endFill();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... to this ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function render() : void&lt;br /&gt;{&lt;br /&gt; if ( isRenderable() )&lt;br /&gt; {&lt;br /&gt;  if ( hasStroke() ) &lt;br /&gt;   graphics.lineStyle( _strokeWidth, _strokeColor );&lt;br /&gt;   &lt;br /&gt;  if ( hasFill() )&lt;br /&gt;   graphics.beginFill( _fillColor );&lt;br /&gt;   &lt;br /&gt;  graphics.drawRect( 0, 0, _displayWidth, _displayHeight );&lt;br /&gt;  graphics.endFill();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... which I hope you'll agree is less of a headache to read. But I still think we can do better. Let's define two more helper methods:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function setFill() : void&lt;br /&gt;{&lt;br /&gt; graphics.beginFill( _fillColor );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function setStroke() : void&lt;br /&gt;{&lt;br /&gt; graphics.lineStyle( _strokeWidth, _strokeColor );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With these puppies available, we can refactor is render to this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function render() : void&lt;br /&gt;{&lt;br /&gt; if ( isRenderable() )&lt;br /&gt; {&lt;br /&gt;  if ( hasStroke() ) setStroke();&lt;br /&gt;   &lt;br /&gt;  if ( hasFill() ) setFill();&lt;br /&gt;   &lt;br /&gt;  graphics.drawRect( 0, 0, _displayWidth, _displayHeight );&lt;br /&gt;  graphics.endFill();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One last migrane: the nested ifs. Is there any way we can make this method have only one level of nesting? Sure there is!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private function render() : void&lt;br /&gt;{&lt;br /&gt; if ( ! isRenderable() ) return;&lt;br /&gt;&lt;br /&gt; if ( hasStroke() ) setStroke();&lt;br /&gt;  &lt;br /&gt; if ( hasFill() ) setFill();&lt;br /&gt;  &lt;br /&gt; graphics.drawRect( 0, 0, _displayWidth, _displayHeight );&lt;br /&gt; graphics.endFill();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now THAT passes the Headache Test!&lt;br /&gt;&lt;br /&gt;Remember, a return instantly cause the method to end. So if the rectangle is not renderable, the code after the first if won't even run.&lt;br /&gt;&lt;br /&gt;Which leaves us with one last headache: the constructor.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function CustomRectangle( displayWidth : Number = 0,&lt;br /&gt;         displayHeight : Number = 0,&lt;br /&gt;         fillColor : uint = Colors.NO_COLOR,&lt;br /&gt;         strokeColor : uint = Colors.NO_COLOR&lt;br /&gt;         strokeWidth : Number = 1 )&lt;br /&gt;{&lt;br /&gt; _displayWidth = displayWidth;&lt;br /&gt; _displayHeight = displayHeight;&lt;br /&gt; _fillColor = fillColor;&lt;br /&gt; _strokeColor = strokeColor;&lt;br /&gt; _strokeWidth = strokeWidth;&lt;br /&gt;&lt;br /&gt; render();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My problem with this is that it has a big parameter list. Looking at that list makes my head spin a little. I'd like the reader to know that that method expects render data and leave it at that. If the reader wants to know more, he can drill down farther. If he doesn't care, he can ignore the details.&lt;br /&gt;&lt;br /&gt;One way to deal with classes that need a lot of set-up data is to make a bunch of little setter methods:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function CustomRectangle() { }&lt;br /&gt;public function set displayWidth ( value : Number ) { _displayWidth = value; }&lt;br /&gt;public function set displayHeight ( value : Number ) { _displayHeight = value; }&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;public function render() : void { ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My problem with this is that it's really hard to tell what you need to do to set up the class and what you is optional. Is it okay to do this?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var rect : CustomRectangle = new CustomRectangle();&lt;br /&gt;rect.displayWidth = 100;&lt;br /&gt;render();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Will this class blow up because I didn't set displayHeight or any of the other properties? Do I have to set them all? Does it matter what order I set them in? The nice thing about variables that get set via constructor calls is that there's no ambiguity. If you forget one, the compiler will yell at you. But this can lead to parameter bloat, as we saw above.&lt;br /&gt;&lt;br /&gt;The solution is to create a new object, a Value Object (a.k.a Data Transfer Object) and pass that to the constructor:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class RenderData&lt;br /&gt;{&lt;br /&gt; public var displayWidth = 0;&lt;br /&gt; public var displayHeight = 0;&lt;br /&gt; public var fillColor : uint = Colors.NO_COLOR;&lt;br /&gt; public var strokeColor : uint = Colors.NO_COLOR;&lt;br /&gt; public var strokeWidth : Number = 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We can now refactor our constructor to this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function CustomRectangle( renderData : RenderData )&lt;br /&gt;{&lt;br /&gt; _displayWidth = renderData.displayWidth;&lt;br /&gt; _displayHeight = renderData.displayHeight;&lt;br /&gt; _fillColor = renderData.fillColor;&lt;br /&gt; _strokeColor = renderData.strokeColor;&lt;br /&gt; _strokeWidth = renderData.strokeWidth;&lt;br /&gt;&lt;br /&gt; render();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or, if we want, we can organize this way:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function CustomRectangle( renderData : RenderData )&lt;br /&gt;{&lt;br /&gt; initWith( renderData );&lt;br /&gt; &lt;br /&gt; render();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function initWith( renderData : RenderData ) : void&lt;br /&gt;{&lt;br /&gt; _displayWidth = renderData.displayWidth;&lt;br /&gt; _displayHeight = renderData.displayHeight;&lt;br /&gt; _fillColor = renderData.fillColor;&lt;br /&gt; _strokeColor = renderData.strokeColor;&lt;br /&gt; _strokeWidth = renderData.strokeWidth;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ah, better than Rolaids and Bufferin combined!&lt;br /&gt;&lt;br /&gt;Here's our final draft. Take a look at this in a month. I bet it will still be instantly clear to you how it works.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Custom Rectangle extends Sprite&lt;br /&gt;{&lt;br /&gt; public function CustomRectangle( renderData : RenderData )&lt;br /&gt; {&lt;br /&gt;  initWith( renderData );&lt;br /&gt;&lt;br /&gt;  render();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function initWith( renderData : RenderData ) : void&lt;br /&gt; {&lt;br /&gt;  _displayWidth = renderData.displayWidth;&lt;br /&gt;  _displayHeight = renderData.displayHeight;&lt;br /&gt;  _fillColor = renderData.fillColor;&lt;br /&gt;  _strokeColor = renderData.strokeColor;&lt;br /&gt;  _strokeWidth = renderData.strokeWidth;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function render() : void&lt;br /&gt; {&lt;br /&gt;  if ( ! isRenderable() ) return;&lt;br /&gt;  &lt;br /&gt;  if ( hasStroke() ) setStroke();&lt;br /&gt;&lt;br /&gt;  if ( hasFill() ) setFill();&lt;br /&gt;&lt;br /&gt;  graphics.drawRect( 0, 0, _displayWidth, _displayHeight );&lt;br /&gt;  graphics.endFill();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function setFill() : void&lt;br /&gt; {&lt;br /&gt;  graphics.beginFill( _fillColor );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private function setStroke() : void&lt;br /&gt; {&lt;br /&gt;  graphics.lineStyle( _strokeWidth, _strokeColor );&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private function isRenderable() : Boolean&lt;br /&gt; {&lt;br /&gt;  if ( hasStroke() || hasFill() ) return true;&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private function hasStroke() : Boolean&lt;br /&gt; {&lt;br /&gt;  if ( _strokeColor != Colors.NO_COLOR ) return true;&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private function hasFill() : Boolean&lt;br /&gt; {&lt;br /&gt;  if ( _fillColor != Colors.NO_COLOR ) return true;&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2229392687786064775?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2229392687786064775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/07/little-lesson-in-refactoring.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2229392687786064775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2229392687786064775'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/07/little-lesson-in-refactoring.html' title='a little lesson in refactoring'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-6115223775406046119</id><published>2009-07-21T11:11:00.000-07:00</published><updated>2009-07-21T11:16:39.060-07:00</updated><title type='text'>the dictionary is mightier than the associative array</title><content type='html'>Developers tend to overlook (or not know about) Dictionaries. In AS 3.0, a Dictionary is similar to an associative array, except it takes objects as keys instead of Strings. Compare this use of an associative array ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var pointsForHittingEnemies : Array = new Array();&lt;br /&gt;pointsForHittingEnemies[ "dracula" ] = 100; &lt;br /&gt;pointsForHittingEnemies[ "mummy" ] = 50; &lt;br /&gt;pointsForHittingEnemies[ "frankenstein" ] = 25; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... with this use of a Dictionary ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import flash.utils.Dictionary;&lt;br /&gt;&lt;br /&gt;var dracula : Monster = new Monster();&lt;br /&gt;var mummy : Monster = new Monster();&lt;br /&gt;var frankenstein : Monster = new Monster();&lt;br /&gt;&lt;br /&gt;var pointsForHittingEnemies : Dictionary = new Dictionary();&lt;br /&gt;pointsForHittingEnemies[ dracula ] = 100; &lt;br /&gt;pointsForHittingEnemies[ mummy ] = 50; &lt;br /&gt;pointsForHittingEnemies[ frankenstein ] = 25; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the second example, note the lack of quotation marks around dracula, mummy and frankenstein. The indices to the Dictionary version of pointForHittingEnemies are objects, not Strings as in the Array version.&lt;br /&gt;&lt;br /&gt;Dictionaries are really useful when you need to associate random bits of data with objects. The way this often rears its head for me is when I want to associate random data with a Sprite. &lt;br /&gt;&lt;br /&gt;Let's say I am making a playlist of videos. I want a button for each video on the list. The buttons will be Sprites, but how do I associate a Sprite with a particular video, so when the user clicks that Sprite, the associated video will play?&lt;br /&gt;&lt;br /&gt;Here's one solution:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import flash.utils.Dictionary;&lt;br /&gt;import flash.display.Sprite;&lt;br /&gt;import flash.events.MouseEvent;&lt;br /&gt;&lt;br /&gt;var videos : Array = ["TheGodfather.flv", "2001.flv","GoneWithTheWind.flv"];&lt;br /&gt;var buttonList : Dictionary;&lt;br /&gt;&lt;br /&gt;init();&lt;br /&gt;&lt;br /&gt;function init() : void&lt;br /&gt;{ &lt;br /&gt; var buttonList = new Dictionary();&lt;br /&gt; var totalVideos : int = videos.length;&lt;br /&gt; for ( var i : int = 0; i &lt; totalVideos; i++ ) makeButton( i );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function makeButtons( index : int ) : void&lt;br /&gt;{&lt;br /&gt; var button : Sprite = new Sprite();&lt;br /&gt; button.buttonMode = true;&lt;br /&gt; button.x = index * 100; //to space buttons out across stage&lt;br /&gt; &lt;br /&gt; //add the button to the Dictionary&lt;br /&gt; //as a key to the video's index&lt;br /&gt; buttonList[ button ] = index;&lt;br /&gt; &lt;br /&gt; //draws stuff on the button (function definition not shown)&lt;br /&gt; renderButton( button );&lt;br /&gt; &lt;br /&gt; addChild( button );&lt;br /&gt; &lt;br /&gt; //take a look at the callback function&lt;br /&gt; //to see how I use the Dictionary&lt;br /&gt; button.addEventListener( MouseEvent.CLICK, buttonClickCallback );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function buttonClickCallback( event : MouseEvent ) : void&lt;br /&gt;{&lt;br /&gt; var button : Sprite = event.currentTarget as Sprite;&lt;br /&gt; &lt;br /&gt; //look up button in the Dictionary and get the&lt;br /&gt; //appropriate video index&lt;br /&gt; var index : int = buttonList[ button ];&lt;br /&gt; &lt;br /&gt; var videoUrl : String = videos[ index ];&lt;br /&gt; &lt;br /&gt; //call to a function that plays a video based on its URL.&lt;br /&gt; //function definition not shown&lt;br /&gt; playVideo( videoUrl ); &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notes: instead of storing indices in my Dictionary, I could have stored the actual URLs of the videos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;buttonList[ button ] = videos[ index ];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this case, I would have written the callback function as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function buttonClickCallback( event : MouseEvent ) : void&lt;br /&gt;{&lt;br /&gt; var button : Sprite = event.currentTarget as Sprite;&lt;br /&gt; &lt;br /&gt; //look up button in the Dictionary and get the&lt;br /&gt; //appropriate video url&lt;br /&gt; var videoUrl : String = buttonList[ videoUrl ];&lt;br /&gt; &lt;br /&gt; //call to a function that plays a video based on its URL.&lt;br /&gt; //function definition not shown&lt;br /&gt; playVideo( videoUrl ); &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I like Dictionaries, because they're simple and powerful. However, I only use them for really quick-fix chores, usually when I'm prototyping something on the Timeline. A more robust solution for associating data with objects is the Class structure:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class VideoButton extends Sprite&lt;br /&gt;{&lt;br /&gt; private var _videoUrl : String;&lt;br /&gt; &lt;br /&gt; public function get videoUrl() : String { return _videoUrl }&lt;br /&gt; public function set videoUrl( value : String ) : void&lt;br /&gt; {&lt;br /&gt;  _videoUrl = value;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, in my main document,  import the VideoButton class and rewrite the makeButtons function as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function makeButtons( index : int ) : void&lt;br /&gt;{&lt;br /&gt; var button : VideoButton = new VideoButton();&lt;br /&gt; button.buttonMode = true;&lt;br /&gt; button.x = index * 100; //to space buttons out across stage&lt;br /&gt; &lt;br /&gt; //store the video's url right in the object itself&lt;br /&gt; button.videoUrl = videos[ index ];&lt;br /&gt; &lt;br /&gt; //draws stuff on the button (function definition not shown)&lt;br /&gt; renderButton( button );&lt;br /&gt; &lt;br /&gt; addChild( button );&lt;br /&gt; &lt;br /&gt; //take a look at the callback function&lt;br /&gt; //to see how I use the Dictionary&lt;br /&gt; button.addEventListener( MouseEvent.CLICK, buttonClickCallback );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the callback will now look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function buttonClickCallback( event : MouseEvent ) : void&lt;br /&gt;{&lt;br /&gt; var button : VideoButton = event.currentTarget as VideoButton;&lt;br /&gt; &lt;br /&gt; //call to a function that plays a video based on its URL.&lt;br /&gt; //function definition not shown&lt;br /&gt; playVideo( button.videoUrl ); &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-6115223775406046119?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/6115223775406046119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/07/dictionary-is-mightier-than-associative.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6115223775406046119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6115223775406046119'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/07/dictionary-is-mightier-than-associative.html' title='the dictionary is mightier than the associative array'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-4301198875303156416</id><published>2009-07-17T08:41:00.000-07:00</published><updated>2009-07-17T08:42:18.571-07:00</updated><title type='text'>parameters suck</title><content type='html'>I'm learning Objective-C, and I've come to love the way you make method calls in that language. If you'd type this in Actionscript...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;shapes.arrow( 0xFF0000, 0x00FF00 )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... you'd type something like this in Objective-C:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[shapes arrowWithStrokeColor: 0xFF0000 andFillColor: 0x00FF00 ]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Though they are more verbose, Objective-C method calls make the purpose of their arguments clear. &lt;br /&gt;&lt;br /&gt;With code, it's more important to cater to the reader than to the writer (who may wish to save himself some keystrokes.) Code gets read many more times than it gets written. If verbosity is the price we have to pay for readable code, it's time to start digging into our wallets.&lt;br /&gt;&lt;br /&gt;I don't want to read shapes.arrow( 0xFF0000, 0x00FF00 ). I can guess that the two hex values are colors, but I don't know which is the fill color and which is the stroke color. To find out, I have to search for the method definition, which is probably in a different file from the one I'm looking at. That slows me down and makes me think about file-navigation in my IDE, rather than about the meaning of the code. &lt;br /&gt;&lt;br /&gt;Unfortunately, Actionscript doesn't give you an elegant solution to this problem, so most developers don't bother trying to solve it. But it's a serious problem, and there are ways to deal with it:&lt;br /&gt;&lt;br /&gt;1) via comments:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// parameters: strokeColor, fillColor&lt;br /&gt;shapes.arrow( 0xFF0000, 0x00FF00 )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is a bad solution, because comments and the code they refer to can easily get out of sync. Say that you (or someone else) changes the definition of shapes.arrow() to...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function arrow( fillColor : uint, strokeColor: uint ) : void { ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... but forgets to update the comment. It will now be an incorrect and misleading comment. This is an easy mistake to make, because the comment and the method definition are in different locations. You might make the update in one place and forget to make it in the other.&lt;br /&gt;&lt;br /&gt;In general, I'm not a fan of comments. It's too easy to use them to explain messy code. It's much better to clean the code.&lt;br /&gt;&lt;br /&gt;2) via descriptive-method names:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;shapes.arrowWithStrokAndFillColor( 0xFF0000, 0x00FF00 )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This tends to stretch method names to the point that they get hard to read, and it get absurd if there are more than a couple of parameters:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;shapes.arrowWithStrokeWidthAndStrokeColorAndFillColor( 1, 0xFF0000, 0x00FF00 );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, in certain cases, when you refer to parameters in method names, it makes the code much easier to read. Compare...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;find( name, names )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... with ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;findItemInList( name, names )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course, if you're using someone else's API, you don't have the luxury of naming their methods. In that case, I recommend...&lt;br /&gt;&lt;br /&gt;3) via variables:&lt;br /&gt;&lt;br /&gt;compare ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;shapes.arrow( 0xFF0000, 0x00FF00 )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... with ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var strokeColor : uint = 0xFF0000;&lt;br /&gt;var fillColor : uint = 0x00FF00;&lt;br /&gt;&lt;br /&gt;shapes.arrow( fillCollor, strokeColor );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is my favorite solution, because it uses code as commentary. Self-commenting code is always better than obscure code with comments. &lt;br /&gt;&lt;br /&gt;Bottom line: when you find yourself typing something like move( object, 1, 5, false, [10,10] ), think about what you can do to make your code readable. You may not have written the move() function, but you did write the call to it. It's your responsibility to use whatever structures exist in your language to make that call clear.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-4301198875303156416?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/4301198875303156416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/07/parameters-suck.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4301198875303156416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4301198875303156416'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/07/parameters-suck.html' title='parameters suck'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-4534171738534957350</id><published>2009-07-17T07:37:00.001-07:00</published><updated>2009-07-17T07:39:59.414-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript 3.0'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>to block or not to block</title><content type='html'>"Best practices" documents tell me to always follow an if, while or for statements with a block of code. They suggest I should type this...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if ( missileHitAlienShip() )&lt;br /&gt;{&lt;br /&gt; score += 100;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...and never this...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if ( missileHitAlienShip() ) score += 100;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I disagree. I find the latter version much easier to read. If you translate the two versions into English, you get "if a missile hits the alien ship, do the following: raise the player's score by 100" and "if a missile hits the alien ship, raise the player's score by 100." I prefer the second version.&lt;br /&gt;&lt;br /&gt;When I present them by themselves, the two versions don't look that different, and the block version isn't all that difficult to read. But when a bunch of blocks are nested inside one another, The code quickly gets difficult to read. Conditional logic gets all mixed up with nitty-gritty implementation details. Compare...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function addToScores() : void&lt;br /&gt;{&lt;br /&gt; if ( levelNumber &gt; 10 )&lt;br /&gt; {&lt;br /&gt;  bonus += 500; &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; for ( var i : int = 0; i &lt; numPlayers; i++ )&lt;br /&gt; {&lt;br /&gt;  player[ i ].score += bonus;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... with ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function addToScores() : void&lt;br /&gt;{&lt;br /&gt; if ( levelNumber &gt; 10 ) bonus += 500;&lt;br /&gt; &lt;br /&gt; for ( var i : int = 0; i &lt; numPlayers; i++ )&lt;br /&gt;   player[ i ].score += bonus;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The "best practices" docs say that you should use blocks because they allow you to easily switch from a single statement to multiple statements. For instance, if I start with something like this...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function addNewAlienShip() : void&lt;br /&gt;{&lt;br /&gt; var ship : AlienShip = new AllienShip();&lt;br /&gt; &lt;br /&gt; if ( shipsHaveWarpDrive ) ship.x = Math.random() * universe.width;&lt;br /&gt; else ship.x = alienBase.x; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... and later realize I need to also set y-coordinates, I'll need to change my code to something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function addNewAlienShip() : void&lt;br /&gt;{&lt;br /&gt; var ship : AlienShip = new AllienShip();&lt;br /&gt; &lt;br /&gt; if ( shipsHaveWarpDrive ) &lt;br /&gt; {&lt;br /&gt;  ship.x = Math.random() * universe.width;&lt;br /&gt;  ship.y = Math.random() * universe.height;&lt;br /&gt; }&lt;br /&gt; else &lt;br /&gt; {&lt;br /&gt;  ship.x = alienBase.x;&lt;br /&gt;  ship.y = alienBase.y;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since I never know how many statements I'll have to add after an if, I might as well start with a block -- as a sort of template -- even if I initially only intend to follow the if with one statement. Or so the "best practices" logic goes.&lt;br /&gt;&lt;br /&gt;I disagree. I'm not a fan of blocks, because they encourage multiple levels of nesting and make methods overly long and hard to read. Given the example above, which may be my initial draft, I'd refactor it as...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function addNewAlienShip() : void&lt;br /&gt;{&lt;br /&gt; var ship : AlienShip = new AllienShip();&lt;br /&gt; &lt;br /&gt; if ( shipsHaveWarpDrive ) putInRandomLocation( ship );&lt;br /&gt; else putInBase( ship );&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;function putInRandomLocation( ship : AlienShip ) : void&lt;br /&gt;{&lt;br /&gt; ship.x = Math.random() * universe.width;&lt;br /&gt; ship.y = Math.random() * universe.height;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function putInBase( ship: AlienShip ) : void&lt;br /&gt;{&lt;br /&gt; ship.x = alienBase.x;&lt;br /&gt; ship.y = alienBase.y;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is easier to read and modular. If I ever want to change the way warp drives place ships, I'll have an easy time doing so without searching through levels of nesting.&lt;br /&gt;&lt;br /&gt;I am not dogmatic about forbidding blocks. If a block seems like a simple and clean solution, I use it. But I initially follow my ifs, whiles and fors with a single statement. If I later realize that I need to add more statements, I make a decision. I sometimes replace the single statement with a block. More often, I turn the single statement into a function call, as I did in the example above.&lt;br /&gt;&lt;br /&gt;A couple of years ago, I turned a major corner in my life as a coder: I started taking three maxims seriously:&lt;br /&gt;&lt;br /&gt;1) each function should do one thing.&lt;br /&gt;2) functions should be as short as possible.&lt;br /&gt;3) nested block are evil.&lt;br /&gt;&lt;br /&gt;Previously, I'd given lip-service to these ideas, but when I started following them religiously, my code got way easier to read and maintain. &lt;br /&gt;&lt;br /&gt;I have found simplicity on the method level to be more important than simplicity on the class level. Since OOP texts mostly focus on classes, many programmers pay more attention to them than to methods. That's like paying more attention to chapters than to sentences. Good writers know that the sentence is where the real work happens. A well organized table of contents is worthless if each chapter is full of non-sensical sentences.&lt;br /&gt;&lt;br /&gt;Again, I am not dogmatic about my three rules, and I often can't follow them when making an initial draft. But when I refactor, I take a close look at any method that is longer than five or six statements. And I take an even closer look at blocks. My goal is to write a group of simple, short functions that each works as one little cog in my big machine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-4534171738534957350?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/4534171738534957350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/07/to-block-or-not-to-block.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4534171738534957350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4534171738534957350'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/07/to-block-or-not-to-block.html' title='to block or not to block'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-5710179002422041185</id><published>2009-07-13T08:58:00.001-07:00</published><updated>2009-07-24T14:05:43.724-07:00</updated><title type='text'>the zen of curly braces</title><content type='html'>As one of the unwashed millions who hopes to make his fame and fortune as an iPhone developer, I've been learning Objective-C. My main teacher has been &lt;a href="http://www.amazon.com/Programming-Objective-C-2-0-Developers-Library/dp/0321566157/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1247498622&amp;sr=8-1"&gt;"Programming in Objective-C 2.0"&lt;/a&gt; by Stephen Kochan, a book which deserves its accolades.&lt;br /&gt;&lt;br /&gt;At some point, Kochan says something like, "In general, you can substitute a block of code for a single statement." I thought about that for a second and realized that, simple as that sounds, I'd never really thought about it before.&lt;br /&gt;&lt;br /&gt;Of course, I know that you can -- in all the c-family languages -- write...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if ( condition ) statement;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if ( condition )&lt;br /&gt;{&lt;br /&gt; block;&lt;br /&gt; of;&lt;br /&gt; statements;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... but I hadn't considered statement/block substitution as a general rule. &lt;br /&gt;&lt;br /&gt;To test things out, I tried this timeline code in an AS3.0 fla:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt; var a : int = 3;&lt;br /&gt; trace( a );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt; for ( var i : int = 0; i &lt; 10; i++ ) trace( i );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And it worked!&lt;br /&gt;&lt;br /&gt;Now, it's not that I think this is useful. I don't. But I love it when I can generalize some specific behaviors into a principle. When this code worked, I felt some contents drifting together. I suddenly understood a bit of Actionscript grammar that I'd never really considered before. &lt;br /&gt;&lt;br /&gt;Actually, I can think of a use for this: refactoring. Say that as a first draft, you write a method like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function init() : void&lt;br /&gt;{&lt;br /&gt; drawBackground();&lt;br /&gt; drawPlayer();&lt;br /&gt; drawEnemies();&lt;br /&gt; setPlayerLives();&lt;br /&gt; setPlayerStartingPosition();&lt;br /&gt; drawPlayerShip();&lt;br /&gt; setEnemyStaringPositions();&lt;br /&gt; setEnemyStrength();&lt;br /&gt; setPlayerStrength();&lt;br /&gt; startGame();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Your first step in refactoring could be to group statements into blocks:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function init() : void&lt;br /&gt;{&lt;br /&gt; {&lt;br /&gt;  drawBackground();&lt;br /&gt;  drawPlayer();&lt;br /&gt;  drawEnemies();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; {&lt;br /&gt;  setPlayerLives();&lt;br /&gt;  setPlayerStartingPosition();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; {&lt;br /&gt;  drawPlayerShip();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; {&lt;br /&gt;  setEnemyStaringPositions();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; {&lt;br /&gt;  setEnemyStrength();&lt;br /&gt;  setPlayerStrength();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; startGame();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I like this, because it suggests groupings without affecting functionality. init should run exactly the way it did before you added the blocks. &lt;br /&gt;&lt;br /&gt;Having added them, you can see some better ways of organizing the statements:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function init() : void&lt;br /&gt;{&lt;br /&gt; {&lt;br /&gt;  drawBackground();&lt;br /&gt;  drawPlayer();&lt;br /&gt;  drawEnemies();&lt;br /&gt;  drawPlayerShip();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; {&lt;br /&gt;  setPlayerLives();&lt;br /&gt;  setPlayerStartingPosition();&lt;br /&gt;  setPlayerStrength();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; {&lt;br /&gt;  setEnemyStaringPositions();&lt;br /&gt;  setEnemyStrength();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; startGame();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This, with a little cutting and pasting, leads naturally to...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public function init() : void&lt;br /&gt;{&lt;br /&gt; renderGamePieces();&lt;br /&gt; initPlayer();&lt;br /&gt; initEnemies();&lt;br /&gt; startGame();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function renderGamePieces() : void &lt;br /&gt;{&lt;br /&gt; drawBackground();&lt;br /&gt; drawPlayer();&lt;br /&gt; drawEnemies();&lt;br /&gt; drawPlayerShip();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function initPlayer() : void&lt;br /&gt;{&lt;br /&gt; setPlayerLives();&lt;br /&gt; setPlayerStartingPosition();&lt;br /&gt; setPlayerStrength();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private function initEnemies() : void&lt;br /&gt;{&lt;br /&gt; setEnemyStaringPositions();&lt;br /&gt; setEnemyStrength();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;incidentally, going back to my original example...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt; var a : int = 3;&lt;br /&gt; trace( a );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt; for ( var i : int = 0; i &lt; 10; i++ ) trace( i );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... I found that double nesting works, too:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt; {&lt;br /&gt;  var a : int = 3;&lt;br /&gt;  trace( a );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; {&lt;br /&gt;  for ( var i : int = 0; i &lt; 10; i++ ) trace( i );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As does triple nesting: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt; {&lt;br /&gt;  {&lt;br /&gt;   var a : int = 3;&lt;br /&gt;   trace( a );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  {&lt;br /&gt;   for ( var i : int = 0; i &lt; 10; i++ ) trace( i );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  {}&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And so on.&lt;br /&gt;&lt;br /&gt;Strangely, this doesn't work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt; var a : int = 3;&lt;br /&gt; trace( a );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt; for ( var i : int = 0; i &lt; 10; i++ ) trace( i );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem here is the semi-colon after the final close-brace. It throws this error:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Syntax error: extra characters found after end of program.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;I got the same error when I added an empty block to the start of the frame code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{}&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt; var a : int = 3;&lt;br /&gt; trace( a );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt; for ( var i : int = 0; i &lt; 10; i++ ) trace( i );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And I also got it when I added an empty block in the middle of the code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt; var a : int = 3;&lt;br /&gt; trace( a );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{}&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt; for ( var i : int = 0; i &lt; 10; i++ ) trace( i );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For some reason (that I don't understand), the AS interpreter assumes it's reached the end of your code when it finds an empty set of braces. The empty set doesn't cause an error on its own, but you will get an error if there are any characters following the the close-brace. This isn't a problem, since I can't think of a reason to ever include an empty block. But I am curious about what's going on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-5710179002422041185?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/5710179002422041185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/07/zen-of-curly-braces.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/5710179002422041185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/5710179002422041185'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/07/zen-of-curly-braces.html' title='the zen of curly braces'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-1832361520433203578</id><published>2009-07-08T14:14:00.001-07:00</published><updated>2009-07-08T14:14:15.376-07:00</updated><title type='text'>Dumb mistakes.</title><content type='html'>Here are a couple of mistakes I make after a long day of coding. Can you spot the errors?&lt;br /&gt;&lt;br /&gt;1. Stack Overflow&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Person&lt;br /&gt;{&lt;br /&gt; private var _name : String;&lt;br /&gt; &lt;br /&gt; public function get name() : String&lt;br /&gt; {&lt;br /&gt;  if ( name == null ) name = "anonymous";&lt;br /&gt;  return _name;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public function set name( value : String ) { _name = value };&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem: run this code and you'll get an output panel full of "stack overflow" errors. Why? Well, take a closer look at the getter method. It's supposed to return the value of private member "_name". But the first statement in the method refers to "name," not "_name" (note the underscore). _name is the private member; name is the getter method. &lt;br /&gt;&lt;br /&gt;When the first statement executes, it tests to see if THE OUTPUT OF THE GETTER METHOD ITSELF is equal to null. Remember, when you type the name of a getter method by itself, you're really just using a syntactic sugar. "name" is really "name()." So what I'm doing in the first statement is similar to this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; function foo() : Number&lt;br /&gt; {&lt;br /&gt;  if ( foo() == null ) trace( "x is equal to null" );&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The call foo() in the first statement calls the function foo, which has a call to foo in the first statement, which calls foo... and so on. An infinite recursive loop. &lt;br /&gt;&lt;br /&gt;In the previous example, I can remove the loop by simply adding underscores to "name":&lt;br /&gt;&lt;br /&gt;bad: if ( name == null ) name = "anonymous";&lt;br /&gt;good: if ( _name == null ) _name = "anonymous";&lt;br /&gt;&lt;br /&gt;Now name is not calling itself; it's referring to a private member called _name.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Null Envy&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var herName : String;&lt;br /&gt;var flower : Sprite;&lt;br /&gt;var sheLovesMe : Boolean;&lt;br /&gt;var herAge : Number;&lt;br /&gt;var kisses : int;&lt;br /&gt;&lt;br /&gt;if ( herName == null ) herName = "Lisa"; //works like a charm&lt;br /&gt;&lt;br /&gt;if ( flower == null ) flower = new Sprite(); //works like a charm&lt;br /&gt;&lt;br /&gt;if ( sheLovesMe == null ) sheLovesMe = false; //error&lt;br /&gt;&lt;br /&gt;if ( herAge == null ) herAge = 18; //error&lt;br /&gt;&lt;br /&gt;if ( kisses == null ) kisses = 0; //error&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem here is that Booleans and numbers types can NEVER be set to null. They don't accept null as a value; nor can they be compared to null. &lt;br /&gt;&lt;br /&gt;Once you define a Boolean, it is automatically set to false. (You can later change its value to true.) There's no such thing as a Boolean with no value, though you can set a Boolean to undefined.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var iLikeCheese : Boolean; //note: not explicitly set to a value&lt;br /&gt;trace( iLikeCheese ); //false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You also can't set or compare a Number to null. Unset numbers are set by default to NaN, which is short for "not a number." However, you can't do this:&lt;br /&gt;&lt;br /&gt;if ( herAge == NaN ) herAge = 18; //error&lt;br /&gt;&lt;br /&gt;Instead, you have to do this:&lt;br /&gt;&lt;br /&gt;if ( isNaN( herAge) ) herAge = 18; //works like a charm&lt;br /&gt;&lt;br /&gt;ints and uints default to zero. If I'm using an int as a uint -- in other words, if my int should never be set to a negative number -- I sometimes set it to negative one by default. For instance, you can't give a girl a negative kiss, so...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static const NOT_SET : int = -1;&lt;br /&gt;&lt;br /&gt;var kisses : int = NOT_SET;&lt;br /&gt;&lt;br /&gt;if ( kisses == NOT_SET ) kisses = 10;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For this reason, I often use ints to store hex-color values. How else should I indicated no color? After all, zero is black. I suppose I could use a uint and define something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public const NO_COLOR : uint = uint.MAX_VALUE; //MAX_VALUE is a built-in constant&lt;br /&gt;&lt;br /&gt;var favoriteColor : uint = NO_COLOR; &lt;br /&gt;&lt;br /&gt;if ( favoriteColor == NO_COLOR ) favoriteColor = 0xFF0000;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This solution is probably good enough for most simple circumstances, but if I need something more robust and scalable, I create a class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Color&lt;br /&gt;{&lt;br /&gt; public static const NO_COLOR : uint = uint.MAX_VALUE;&lt;br /&gt; private var _color : uint = Color.NO_COLOR;&lt;br /&gt; &lt;br /&gt; public function get color() : uint { return _color; }&lt;br /&gt; public function set color( value : uint ) { _color = value; }&lt;br /&gt; public function isSet() : Boolean { return _color == Color.NO_COLOR; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-1832361520433203578?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/1832361520433203578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/07/dumb-mistakes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1832361520433203578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/1832361520433203578'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/07/dumb-mistakes.html' title='Dumb mistakes.'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2995218990737863387</id><published>2009-07-08T09:48:00.000-07:00</published><updated>2009-07-08T12:15:33.611-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript 3.0'/><title type='text'>looping through a class's static members</title><content type='html'>How do you loop through all static members of a class? &lt;br /&gt;&lt;br /&gt;First of all, why would you want to do that? Well, let's say you're writing a game in which the player can move in the four classic compass directions:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Directions&lt;br /&gt;{&lt;br /&gt; public static const NORTH : String = "north";&lt;br /&gt; public static const SOUTH : String = "south";&lt;br /&gt; public static const EAST : String = "east";&lt;br /&gt; public static const WEST : String = "west";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Somewhere in your game, you have a moveInDirection() method that accepts a direction. But you want to make sure it doesn't try to move the player in illegal directions, e.g. moveInDirection("up"); The IDE should prevent this, because if you type moveInDirection(Directions.UP) you'll get an error (because there's no UP constant). &lt;br /&gt;&lt;br /&gt;However, I'd like to make moveInDirection a bit more idiot proof than having it rely on the IDE. Also, it's possible that directions may be chosen at run time. For instance, a player might type a direction in a textfield, as in a text-adventure game. What if the player types "up"?&lt;br /&gt;&lt;br /&gt;So I'd like moveInDirection() to check if the player is trying to make a legal move...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function movieInDirection( direction : String ) : void&lt;br /&gt;{&lt;br /&gt; if ( isLegal( direction ) )&lt;br /&gt; {&lt;br /&gt;  ...&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The question is, how should isLegal() work? The last thing I want to do is to use a bunch of conditionals or an Array...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function isLegal( direction : String ) : Boolean&lt;br /&gt;{&lt;br /&gt; var legal : Array = [ "north", "south", "east", "west" ];&lt;br /&gt; &lt;br /&gt; for each ( var legalDirection : String in legal )&lt;br /&gt; {&lt;br /&gt;   if ( direction == legalDirection ) return true;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's a terrible solution, because it couples the class Directions to the Array in my isLegal function. Scaling will be dangerous. For instance, what if I add a new constant to Directions...&lt;br /&gt;&lt;br /&gt;public static const INSIDE : String = "inside";&lt;br /&gt;&lt;br /&gt;... but forget to add it to the Array?&lt;br /&gt;&lt;br /&gt;var legal : Array = [ "north", "south", "east", "west" ]; //Oops! Forgot to add "inside"&lt;br /&gt;&lt;br /&gt;A better solution is to loop through all the constants in Directions and check if the player's attempted direction exists. But how do you loop through all the static members of a class? After playing around with arcane solutions involving prototype chains, I settled on using the little-known describeType() function. It's in the flash.utils class, and you import it like this:&lt;br /&gt;&lt;br /&gt;import flash.utils.describeType;&lt;br /&gt;&lt;br /&gt;If you feed describleType() the Directions class -- trace( describeType( Directions) ) -- it outputs an XML description of the class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;type name="Directions" base="Class" isDynamic="true" isFinal="true" isStatic="true"&amp;gt;&lt;br /&gt;  &amp;lt;extendsClass type="Class"/&amp;gt;&lt;br /&gt;  &amp;lt;extendsClass type="Object"/&amp;gt;&lt;br /&gt;  &amp;lt;constant name="WEST" type="String"/&amp;gt;&lt;br /&gt;  &amp;lt;constant name="NORTH" type="String"/&amp;gt;&lt;br /&gt;  &amp;lt;constant name="EAST" type="String"/&amp;gt;&lt;br /&gt;  &amp;lt;constant name="SOUTH" type="String"/&amp;gt;&lt;br /&gt;  &amp;lt;accessor name="prototype" access="readonly" type="*" declaredBy="Class"/&amp;gt;&lt;br /&gt;  &amp;lt;factory type="Directions"&amp;gt;&lt;br /&gt;    &amp;lt;extendsClass type="Enum"/&amp;gt;&lt;br /&gt;    &amp;lt;extendsClass type="Object"/&amp;gt;&lt;br /&gt;  &amp;lt;/factory&amp;gt;&lt;br /&gt;&amp;lt;/type&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It's then a fairly easy matter to parse the xml, extract all the constants, and test them against the player's choice. I packaged the solution in a utility class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package com.grumblebee.constants &lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;import flash.utils.describeType;    &lt;br /&gt;&lt;br /&gt;  public class Utilities &lt;br /&gt;  {&lt;br /&gt;     public static function isLegal( enumClass : Class, value : String ) : Boolean&lt;br /&gt;     {&lt;br /&gt;        var xml : XML = describeType( enumClass );&lt;br /&gt;        var xmlList : XMLList = xml.child( "constant" );&lt;br /&gt;        var enumName : String;&lt;br /&gt;      &lt;br /&gt;        for each ( var child : XML in xmlList )&lt;br /&gt;        {&lt;br /&gt;          enumName = child.attribute( "name" ).toString();&lt;br /&gt;          if ( enumClass[ enumName ] == value ) return true;&lt;br /&gt;        }&lt;br /&gt;   &lt;br /&gt;        return false;&lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I can't shake the feeling that there's a better way to do this. I'd love to lose the XML parsing. But this is the best I can come up with for the moment. One thing I could do is transform the player's string to upper-case and test it directly to see if there's such a constant in Directions:&lt;br /&gt;&lt;br /&gt;if ( Directions[ playerString.toUpperCase() ] != undefined ) ...&lt;br /&gt;&lt;br /&gt;But that only works if I stick to the convention of NORTH = "north". It fails if Directions looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Directions&lt;br /&gt;{&lt;br /&gt; public static const NORTH : String = "n";&lt;br /&gt; public static const SOUTH : String = "s";&lt;br /&gt; public static const EAST : String = "e";&lt;br /&gt; public static const WEST : String = "w";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;it would also fail in the case of...&lt;br /&gt;&lt;br /&gt;public static const UNDER_THE_BRIDGE : String = "under the bridge";&lt;br /&gt;&lt;br /&gt;At one point, I thought about adding the isLegal() function to Directions. You can get a class to refer to its own static constants this way:&lt;br /&gt;&lt;br /&gt;trace( prototype.constructor[ "NORTH" ] ); //north&lt;br /&gt;&lt;br /&gt;Sadly, though prototype.constructor allows you to access individual class variables and constants, for some reason, you can't loop through its members:&lt;br /&gt;&lt;br /&gt;for each ( var s: String in prototype.constant ) trace( prototype.constant[ s ] ); //no output&lt;br /&gt;&lt;br /&gt;It also doesn't work if you explicitly name the class:&lt;br /&gt;&lt;br /&gt;trace( Directions[ "NORTH"] ); //north&lt;br /&gt;for each ( var s : String in Directions ) trace( Directions[ s ] ); //no output.&lt;br /&gt;&lt;br /&gt;So until something better comes along, I'm stuck with XML parsing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2995218990737863387?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2995218990737863387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/07/looping-through-classs-static-members.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2995218990737863387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2995218990737863387'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/07/looping-through-classs-static-members.html' title='looping through a class&apos;s static members'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-6306845189928863793</id><published>2009-06-06T21:36:00.000-07:00</published><updated>2009-06-06T22:32:45.575-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript factory factories oop conditional conditionals switch case if'/><title type='text'>ditch conditionals; use factories</title><content type='html'>When I first started coding, I used a lot of switch/case statements and complex ifs. But over the years, I become suspicious of them. Now, when I feel the urge to reach for a switch/case, I slap my wrist and try to come up with a better construct. &lt;br /&gt;&lt;br /&gt;To demonstrate the problem, I've come up with a toy example: an app that fills the stage with little Fisher-Price-type people. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_eeOpXM9pWmE/SitOkFM0WtI/AAAAAAAAABg/v2pEJ6YvjlA/s1600-h/people.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 393px; height: 400px;" src="http://2.bp.blogspot.com/_eeOpXM9pWmE/SitOkFM0WtI/AAAAAAAAABg/v2pEJ6YvjlA/s400/people.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5344451764583422674" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are two types of people, bald people and hairy people. Just before placing a person on the stage, my app randomly chooses if he's going to have hair or not. Bald people are all members of the Person class; Hairy folks are members of the HairyPerson class. To create such classes, I do this:&lt;br /&gt;&lt;br /&gt;var person1 : Person = Person( new bald() );&lt;br /&gt;var person2 : Person = HairyPerson( new hairy() );&lt;br /&gt;&lt;br /&gt;Note that I type both sorts of people to Person. I can do that because HairyPerson is a subclass of Person (and subclasses can be typed to their parent's type). By giving the vars the same type, I can pass them both into functions that expect a Person type, and those functions will work regardless of whether the person is a Person or a HairyPerson. &lt;br /&gt;&lt;br /&gt;What are those new bald() and new hairy() calls doing for me? bald and hairy are MovieClips in my FLA's Library. Person classes must be passed a reference to a MovieClip. They use the clip as base artwork, which they then customize via random colors. If you want to know more about Person construction, you can check out &lt;a href="http://grumblebee.com/grumblecode/people.zip"&gt;my FLA and AS files&lt;/a&gt;, but the details aren't important to this post, so I won't elaborate here.&lt;br /&gt;&lt;br /&gt;The question is this: in my Document class, where I randomly choose types of people, how do I instantiate type chosen at random? In the past, I would have done it this way:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;for ( var i : int = 0; i &amp;lt; 100; i++ )&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rand = Math.floor( Math.random() * 2 );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch ( rand ) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case 0 :&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person = new Person( new bald() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case 1 :&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person = new HairyPerson( new hairy() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.render();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.x = Math.random() * Stage.stageWidth;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.y = Math.random() * Stage.stageHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;addChild( person );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;The problem with this is that it doesn't scale well. If I add another type of person, say a HatWearingPerson, I need to add another case -- and I need to change my Math.random() statement so that it is range includes my new case:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;for ( var i : int = 0; i &amp;lt; 100; i++ )&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rand = Math.floor( Math.random() * 3 ); //2 changed to 3&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch ( rand ) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case 0 :&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person = new Person( new bald() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case 1 :&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person = new HairyPerson( new hairy() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case 2 : //added&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person = new HatWearingPerson( new hatWearer() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.render();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.x = Math.random() * Stage.stageWidth;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.y = Math.random() * Stage.stageHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;addChild( person );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;This isn't such a big deal in my toy example, but imagine a more complex system in which you were constantly adding and removing types of people. Not only would I have to create the new classes; I'd also have to remember to add (or remove) new cases to the switch/case statement and to update the Math.random() statement. Eventually -- probably sooner rather than later -- I'm going to screw up and forget to add a case or forget to update Math.random().&lt;br /&gt;&lt;br /&gt;But the bigger problem is that my Document class and the people classes are tightly coupled. Good OOP practice tells me that those person-instantiation statements shouldn't be hard coded into the Document class. Classes should be as independent from each other as possible, so that you wind up with a modular system in which you can change one class without having to change another.&lt;br /&gt;&lt;br /&gt;What's the alternative? Factory classes! Factories are classes that make instances of other classes: Here are mine:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public class PersonFactory implements IPersonFactory&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public function getPerson() : Person&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var person : Person = new Person( new bald() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return person;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public class HairyPersonFactory implements IPersonFactory&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public function getPerson() : Person&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var person : Person = new HairyPerson( new hairy() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return person;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public class HatWearingPersonFactory implements IPersonFactory&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public function getPerson() : Person&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var person : Person = new HatWearingPerson( new hatwearer() );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return person;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;As you can see, these classes all implement an interface called IPersonFactory. You'll see how this helps me out in a second. In the meantime, here's the interface:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;package&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public interface IPersonFactory&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function getPerson() : Person;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;My new and improved Document class looks like this:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;var person : Person;&lt;br /&gt;var rand : int;&lt;br /&gt;var factories : Array;&lt;br /&gt;&lt;br /&gt;addFactory( new PersonFactory ); //see addFactory(), below&lt;br /&gt;addFactory( new HairyPersonFactory );&lt;br /&gt;addFactory( new FancyPersonFactory );&lt;br /&gt;&lt;br /&gt;for ( var i : int = 0; i &amp;lt; 100; i++ )&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rand = Math.floor( Math.random() * factories.length );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person = factories[ rand ].getPerson();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.render();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.x = Math.random() * stage.stageWidth;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;person.y = Math.random() * stage.stageHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;addChild( person );&lt;br /&gt;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;function addFactory( factory : IPersonFactory ) : void&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;factories.push( factory );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Note that the addFactory function accepts any class that implements the IFactory interface, so my Document class doesn't know -- or need to know -- how many types of people (or people factories) exists.&lt;br /&gt;&lt;br /&gt;From now on, if I add a new Person subclass, I just need to make a factory for it and pass that factory to my the Document class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-6306845189928863793?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/6306845189928863793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/06/ditch-conditionals-use-factories.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6306845189928863793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6306845189928863793'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/06/ditch-conditionals-use-factories.html' title='ditch conditionals; use factories'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_eeOpXM9pWmE/SitOkFM0WtI/AAAAAAAAABg/v2pEJ6YvjlA/s72-c/people.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2466082694697221023</id><published>2009-06-05T13:48:00.000-07:00</published><updated>2009-06-05T14:02:41.112-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript testing fla Flash ide'/><title type='text'>visual test toolkit</title><content type='html'>I'm a big fan of the Flash player, the SWF format and the Actionscript language, but I'm not crazy about the Flash IDE. It belongs on the B-list of many categories. &lt;br /&gt;&lt;br /&gt;Want an animation tool? Check out After Effects (or Toon Boom Studio). Flash is a light-weight by comparison. Want a vector-drawing app? Use Illustrator (especially now that it has the &lt;a href="http://www.layersmagazine.com/illustrator-cs4-blob-brush.html"&gt;Blob Brush&lt;/a&gt;!). Want a coding IDE? Use Flex or FDT. Flash dips its toes into many pools but refuses to dive into any of them.&lt;br /&gt;&lt;br /&gt;However, I do find Flash useful for one thing -- so useful that I start it up at least once a day: Flash is a faux command-line interpreter for Actionscript! It's not really an interpreter, of course. It's more of a compiler. But it beats everything else for quickly trying out a bit of Actionscript. You don't need to create a project, a class or even a function. Just throw some code on the timeline, press Command+Enter and Bob's your uncle. That's a terrible way to code anything real, but it's a great way to quickly test out a bit of functionality. &lt;br /&gt;&lt;br /&gt;Sometimes, when I'm doing these tests, I need visual elements. And I waste time creating little circles, square and text fields. So I quit doing that. Instead, I created a little testing file that I use over and over. It's got a stage full of doodads and whatnots, and everything is labeled with its instance name. Also, items in the library have Export for Actionscript turned on, so I can create new instances with code if need be. &lt;br /&gt;&lt;br /&gt;I leave this file open all day, with frame 1 of the timeline exposed in the AS editor. If I need to run a quick test, I'm all set to go.&lt;br /&gt;&lt;br /&gt;Here's the &lt;a href="http://www.grumblebee.com/grumblecode/stuff.fla"&gt;file&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_eeOpXM9pWmE/SimG-P7S-1I/AAAAAAAAABY/Ve_eRZrtV4s/s1600-h/teststuff,jpg.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 297px;" src="http://2.bp.blogspot.com/_eeOpXM9pWmE/SimG-P7S-1I/AAAAAAAAABY/Ve_eRZrtV4s/s400/teststuff,jpg.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5343950836837055314" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2466082694697221023?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2466082694697221023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/06/visual-test-toolkit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2466082694697221023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2466082694697221023'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/06/visual-test-toolkit.html' title='visual test toolkit'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_eeOpXM9pWmE/SimG-P7S-1I/AAAAAAAAABY/Ve_eRZrtV4s/s72-c/teststuff,jpg.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-2256824687818766741</id><published>2009-06-02T09:35:00.000-07:00</published><updated>2009-06-02T09:49:04.293-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='getters setters oop actionscript air app'/><title type='text'>generating getters and setters</title><content type='html'>I'm down with OOP and using getters and setting instead of exposing class member variables, but making getters and setters is a pain. Flex and FTD have tools to help automate the process, but they don't automate it enough. I wanted to be able to type in a list of vars like this...&lt;br /&gt;&lt;br /&gt;private var _newWidth  : Number;&lt;br /&gt;private var _newHeight  : Number;&lt;br /&gt;private var _scaleList : Array;&lt;br /&gt;private var _moveList : Array;&lt;br /&gt;private var _oldWidth : Number;&lt;br /&gt;private var _oldHeight : Number;&lt;br /&gt;private var _widthPercentChange : Number;&lt;br /&gt;private var _heightPercentChange : Number;&lt;br /&gt;&lt;br /&gt;... and, via a single click, get this...&lt;br /&gt;&lt;br /&gt;public function get newWidth() : Number&lt;br /&gt;{&lt;br /&gt;    return _newWidth;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set newWidth( value : Number ) : void&lt;br /&gt;{&lt;br /&gt;    _newWidth = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function get newHeight() : Number&lt;br /&gt;{&lt;br /&gt;    return _newHeight;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set newHeight( value : Number ) : void&lt;br /&gt;{&lt;br /&gt;    _newHeight = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function get scaleList() : Array&lt;br /&gt;{&lt;br /&gt;    return _scaleList;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set scaleList( value : Array ) : void&lt;br /&gt;{&lt;br /&gt;    _scaleList = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function get moveList() : Array&lt;br /&gt;{&lt;br /&gt;    return _moveList;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set moveList( value : Array ) : void&lt;br /&gt;{&lt;br /&gt;    _moveList = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function get oldWidth() : Number&lt;br /&gt;{&lt;br /&gt;    return _oldWidth;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set oldWidth( value : Number ) : void&lt;br /&gt;{&lt;br /&gt;    _oldWidth = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function get oldHeight() : Number&lt;br /&gt;{&lt;br /&gt;    return _oldHeight;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set oldHeight( value : Number ) : void&lt;br /&gt;{&lt;br /&gt;    _oldHeight = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function get widthPercentChange() : Number&lt;br /&gt;{&lt;br /&gt;    return _widthPercentChange;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set widthPercentChange( value : Number ) : void&lt;br /&gt;{&lt;br /&gt;    _widthPercentChange = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function get heightPercentChange() : Number&lt;br /&gt;{&lt;br /&gt;    return _heightPercentChange;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function set heightPercentChange( value : Number ) : void&lt;br /&gt;{&lt;br /&gt;    _heightPercentChange = value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;And now I can, because I built a little AIR app to do it for me. I can copy in the private vars, press the GENERATE button, and -- BINGO! -- out pops my getters and setters. Then I can click the COPY button, which copies the getters and setters to the clipboard. Finally, I can paste them into Flex or FDT.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_eeOpXM9pWmE/SiVXEVG2UVI/AAAAAAAAABQ/M6Z50zdxcoI/s1600-h/gsMaker.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 175px; height: 400px;" src="http://3.bp.blogspot.com/_eeOpXM9pWmE/SiVXEVG2UVI/AAAAAAAAABQ/M6Z50zdxcoI/s400/gsMaker.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5342772264841924946" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's a &lt;a href="http://grumblebee.com/grumblecode/gsMaker.air"&gt;link&lt;/a&gt; to the app.&lt;br /&gt;&lt;br /&gt;Notes: it is template-based, so if you don't like the code it generates, it's easy to make it do what you want. Click HELP for more info. &lt;br /&gt;&lt;br /&gt;Also, please note that though this is a useful tool, it can be abused. For instance, some properties should be read only. They shouldn't have a setter. So use with caution and good OOP practices!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-2256824687818766741?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/2256824687818766741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/06/generating-getters-and-setters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2256824687818766741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/2256824687818766741'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/06/generating-getters-and-setters.html' title='generating getters and setters'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_eeOpXM9pWmE/SiVXEVG2UVI/AAAAAAAAABQ/M6Z50zdxcoI/s72-c/gsMaker.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-4834612036837459783</id><published>2009-06-02T07:17:00.000-07:00</published><updated>2009-06-02T07:22:07.837-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rss opml actionscript vienna blogs feeds'/><title type='text'>keeping up with the actionscript joneses</title><content type='html'>I use an RSS reader called &lt;a href="http://www.vienna-rss.org/vienna2.php"&gt;Vienna&lt;/a&gt; to keep up with Actionscript news. Over time, I've compiled a big list of AS-related blogs, which I've now published as in &lt;a href="http://en.wikipedia.org/wiki/OPML"&gt;opml&lt;/a&gt; file. Feel free to &lt;a href="http://grumblebee.com/grumblecode/actionscript.opml"&gt;download&lt;/a&gt; it an import it into Vienna (File &gt; Import). I'll update the opml when I find new feeds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-4834612036837459783?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/4834612036837459783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/06/keeping-up-with-actionscript-joneses.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4834612036837459783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/4834612036837459783'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/06/keeping-up-with-actionscript-joneses.html' title='keeping up with the actionscript joneses'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-8744433308055094425</id><published>2009-06-01T14:03:00.000-07:00</published><updated>2009-09-29T13:38:32.936-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac osx apps applications'/><title type='text'>mac apps</title><content type='html'>I work on a mac. Here are the apps I use in my work. I'll update this list when I start using new apps or quit using old ones.&lt;br /&gt;&lt;br /&gt;MEDIA&lt;br /&gt;&lt;a href="http://www.videolan.org/vlc/"&gt;Vlc&lt;/a&gt;. This is a one-stop-shop video player that plays virtually any format. &lt;br /&gt;&lt;br /&gt;WRITING&lt;br /&gt;&lt;a href="http://macromates.com/"&gt;Textmate&lt;/a&gt;. The best text editor I've ever found for the Mac. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/macvim/"&gt;MacVim &lt;/a&gt;(free). The old Unix editor wrapped with a Mac GUI. Edit code without touching the mouse.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.openoffice.org/"&gt;Open Office&lt;/a&gt; (free). Open-source MS Office replacement.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.smileonmymac.com/TextExpander/"&gt;TextExpander&lt;/a&gt;. Allows you to make system-wide keyboard shortcuts that expand into blocks of text. For instance, on my system, typing aaaa expands to my complete mailing address. You can set up shortcuts that work only in specific apps. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://slidepad-mac.com/"&gt;Slidepad&lt;/a&gt;. Neat little text-editor that slides on and off the screen via a keyboard shortcut. I used it for on-the-fly, temporary notes.&lt;br /&gt;&lt;br /&gt;INFO MANAGEMENT&lt;br /&gt;&lt;a href="http://evernote.com/"&gt;Evernote&lt;/a&gt; (free). A fantastic app that lets you keep track of any sort of information. It can sync to multiple computers, the web, and many mobile devices (including the iPhone). &lt;br /&gt;&lt;br /&gt;APP LAUNCHING&lt;br /&gt;&lt;a href="http://amarsagoo.info/namely/"&gt;Namely&lt;/a&gt; (free). Allows you to launch any Mac app via the keyboard. It's a lightweight alternative to Quicksilver, which always bogs down my system.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mac.softpedia.com/get/Utilities/Launcher-StaS-Bandol.shtml"&gt;LauncherConfig&lt;/a&gt; (free). Launches multiple files at once. I use it every morning to launch iChat, my mail client, my svn client, my ftp client and my Twitter client with one click.&lt;br /&gt;&lt;br /&gt;WEB BROWSING&lt;br /&gt;&lt;a href="http://www.mozilla.com/en-US/firefox/personal.html"&gt;Firefox&lt;/a&gt; Browser (free). I await a Mac version of &lt;a href="http://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.getfirebug.com/"&gt;Firebug&lt;/a&gt; (free). THE must-have Firefox plugin for web developers. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://fluidapp.com/"&gt;Fluid&lt;/a&gt; (free). Allows you turn web pages into stand-alone apps. I use it so that I can easily launch gmail into its own window.&lt;br /&gt;&lt;br /&gt;DEVELOPMENT&lt;br /&gt;&lt;a href="http://labs.adobe.com"&gt;Flash Builder 4&lt;/a&gt; (formerly Flex Builder). This is my main coding tool. I used to use &lt;a href="http://fdt.powerflasher.com/"&gt;FDT&lt;/a&gt;, which is terrific, but Flash Builder has now outgunned it. Flash Builder is the best AS (and MXML) editor out there.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.aptana.com/"&gt;Aptana Studio&lt;/a&gt; (FREE). A one-stop show IDE for HTML, CSS, Javascript, Python, Ruby and PHP. It's Eclipse-based.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mamp.info/"&gt;MAMP&lt;/a&gt; (free). An Apache server for the Mac. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://gskinner.com/RegExr/desktop/"&gt;RegExp Tool&lt;/a&gt; (free). This is the best app I've every found for testing out Regular Expressions.&lt;br /&gt;&lt;br /&gt;DESIGN&lt;br /&gt;&lt;a href="http://www.adobe.com"&gt;Adobe CS4 Suite&lt;/a&gt;. Of course.&lt;br /&gt;&lt;br /&gt;REMOTE FILE MANAGEMENT&lt;br /&gt;&lt;a href="http://www.panic.com/transmit/"&gt;Transmit&lt;/a&gt;. My FTP client of choice. It allows you to edit files while they're online.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.syncrosvnclient.com/"&gt;Syncro SVN Client&lt;/a&gt;. Full-featured GUI client for the Mac.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://zumodrive.com/"&gt;Zumodrive&lt;/a&gt; (free for 1GB, $ for more). A virtual harddrive that you can access from anywhere.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.transmissionbt.com/"&gt;Transmission&lt;/a&gt;. Solid bittorrent client.&lt;br /&gt;&lt;br /&gt;SOCIALIZING&lt;br /&gt;&lt;a href="http://colloquy.info/downloads.html"&gt;Colloquay&lt;/a&gt; (free). All-you-need IRC client.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.atebits.com/tweetie-mac/"&gt;Tweetie&lt;/a&gt; (free if you use add-supported version). Solid Twitter client for the Mac (and iPhone).&lt;br /&gt;&lt;br /&gt;EMULATING&lt;br /&gt;&lt;a href="http://www.virtualbox.org/"&gt;Virtual Box&lt;/a&gt; (free). Run Windows on the Mac. Like &lt;a href="http://www.parallels.com/"&gt;Parallels&lt;/a&gt;, but free. &lt;br /&gt;&lt;br /&gt;READING&lt;br /&gt;&lt;a href="http://www.vienna-rss.org/vienna2.php"&gt;Vienna&lt;/a&gt; (free). RSS reader with a build-in Browser. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://amarsagoo.info/tofu/"&gt;Tofu&lt;/a&gt; (free). Paste text into this cool tool, and it formats the text into narrow columns, which makes online reading much easier. It's the closest you'll get to a Kindle on your computer screen.&lt;br /&gt;&lt;br /&gt;MISC&lt;br /&gt;&lt;a href="http://www.versiontracker.com/dyn/moreinfo/macosx/33802"&gt;Eigenclock&lt;/a&gt; (free). Replacement for the system clock. Includes a dropdown calendar.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lightheadsw.com/caffeine/"&gt;&lt;br /&gt;Caffeine&lt;/a&gt; (free). Lets you temporarily disable sleep, so that your monitor doesn't power down. Useful if you're watching a long video.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.stclairsoft.com/DefaultFolderX/"&gt;Default Folder X&lt;/a&gt;. I seriously don't know how I lived without this. It wraps open, save and save-as dialogs inside a feature-packed window containing shortcuts to folders you need to access quickly. You can define any shortcuts you want.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-8744433308055094425?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/8744433308055094425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/06/mac-apps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8744433308055094425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/8744433308055094425'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/06/mac-apps.html' title='mac apps'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-6902788270237479648</id><published>2009-05-31T10:37:00.000-07:00</published><updated>2009-05-31T15:13:30.108-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript text color regexp regularexpression textfield'/><title type='text'>colorizing text as you type</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_eeOpXM9pWmE/SiLKfaV8hyI/AAAAAAAAAA4/apAl1NnWVp4/s1600-h/words.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 198px;" src="http://2.bp.blogspot.com/_eeOpXM9pWmE/SiLKfaV8hyI/AAAAAAAAAA4/apAl1NnWVp4/s400/words.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5342054749010954018" /&gt;&lt;/a&gt;&lt;br /&gt;For a project I worked on, I needed an input TextTield that would colorize specific kinds of words as the user is typing them. For instance, if the user types "To @be or not to be, @that is the @question," I need the words starting with at-signs to turn red. And, as I said, I needed this to happen "live," as the user types. In other words, "@be" needs to turn red before the user types "or."&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's the Regular Expression I used: /\B@[A-Za-z0-9]+/g&lt;br /&gt;&lt;br /&gt;It starts by looking for a word boundary (\B). This is so it will match @be but not the @be in bumble@bee. More important, I don't want it to match email addresses, which have at-signs in the middle. My RegExp will only match words starting with at-signs. &lt;br /&gt;&lt;br /&gt;Next in the RegExp, I added the literal @ and then [A-Za-z0-9]+, which will match any number of characters, as long they are letters or digits. Finally, I added the global switch (g), so that the RegExp would match all @words, not just the first one it finds.&lt;br /&gt;&lt;br /&gt;Here's the code, followed by some notes:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;input&lt;/b&gt;&lt;/font&gt;&amp;nbsp;: &lt;font color="#b02f60"&gt;&lt;b&gt;TextField&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;&lt;br /&gt;&lt;font color="#008b00"&gt;&lt;b&gt;input&lt;/b&gt;&lt;/font&gt;.&lt;font color="#458b73"&gt;addEventListener&lt;/font&gt;( Event.CHANGE, onTextChange);&lt;br /&gt;&lt;br /&gt;&lt;font color="#458b73"&gt;function&lt;/font&gt;&amp;nbsp;onTextChange( event : Event ) : &lt;font color="#cc0000"&gt;void&lt;/font&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;tfSpecial : &lt;font color="#b02f60"&gt;&lt;b&gt;TextFormat&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#b02f60"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;TextFormat&lt;/b&gt;&lt;/font&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;tfDefault : &lt;font color="#b02f60"&gt;&lt;b&gt;TextFormat&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#b02f60"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;TextFormat&lt;/b&gt;&lt;/font&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;allText : &lt;font color="#b02f60"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#008b00"&gt;&lt;b&gt;input&lt;/b&gt;&lt;/font&gt;.&lt;font color="#008b00"&gt;&lt;b&gt;text&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;caretIndex&lt;/b&gt;&lt;/font&gt;&amp;nbsp;: &lt;font color="#b02f60"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#008b00"&gt;&lt;b&gt;input&lt;/b&gt;&lt;/font&gt;.&lt;font color="#008b00"&gt;&lt;b&gt;caretIndex&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;startIndex : &lt;font color="#b02f60"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= ( caretIndex - &lt;font color="#cc0000"&gt;100&lt;/font&gt;&amp;nbsp;&amp;lt; &lt;font color="#cc0000"&gt;0&lt;/font&gt;&amp;nbsp;) ? &lt;font color="#cc0000"&gt;0&lt;/font&gt;&amp;nbsp;: &lt;font color="#008b00"&gt;&lt;b&gt;caretIndex&lt;/b&gt;&lt;/font&gt;&amp;nbsp;- &lt;font color="#cc0000"&gt;100&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;localText : &lt;font color="#b02f60"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= allText.&lt;font color="#008b00"&gt;&lt;b&gt;substr&lt;/b&gt;&lt;/font&gt;( startIndex, caretIndex );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff8b00"&gt;regExp&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;font color="#ff8b00"&gt;RegExp&lt;/font&gt;&amp;nbsp;= &lt;font color="#b02f60"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff8b00"&gt;RegExp&lt;/font&gt;( /&lt;font color="#8a2ae2"&gt;\B&lt;/font&gt;@[^ ]+/g );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;obj&lt;/b&gt;&lt;/font&gt;&amp;nbsp;: &lt;font color="#b02f60"&gt;&lt;b&gt;Object&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#ff8b00"&gt;regExp&lt;/font&gt;.&lt;font color="#458b73"&gt;exec&lt;/font&gt;( localText );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tfSpecial.&lt;font color="#008b00"&gt;&lt;b&gt;color&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#cc0000"&gt;0xFF0000&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tfSpecial.&lt;font color="#008b00"&gt;&lt;b&gt;bold&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#cc0000"&gt;true&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tfDefault.&lt;font color="#008b00"&gt;&lt;b&gt;color&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#cc0000"&gt;0x000000&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tfDefault.&lt;font color="#008b00"&gt;&lt;b&gt;bold&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#cc0000"&gt;false&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;input&lt;/b&gt;&lt;/font&gt;.&lt;font color="#008b00"&gt;&lt;b&gt;setTextFormat&lt;/b&gt;&lt;/font&gt;( tfDefault, allText.&lt;font color="#008b00"&gt;&lt;b&gt;length&lt;/b&gt;&lt;/font&gt;&lt;font color="#cc0000"&gt;-1&lt;/font&gt;, allText.&lt;font color="#008b00"&gt;&lt;b&gt;length&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/font&gt;( obj != &lt;font color="#cc0000"&gt;null&lt;/font&gt;&amp;nbsp;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;input&lt;/b&gt;&lt;/font&gt;.&lt;font color="#008b00"&gt;&lt;b&gt;setTextFormat&lt;/b&gt;&lt;/font&gt;( tfSpecial, obj[ &lt;font color="#4a6f8b"&gt;&amp;quot;index&amp;quot;&lt;/font&gt;&amp;nbsp;],&amp;nbsp;&amp;nbsp;obj[ &lt;font color="#4a6f8b"&gt;&amp;quot;index&amp;quot;&lt;/font&gt;&amp;nbsp;] + &lt;font color="#b02f60"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;( obj ).&lt;font color="#008b00"&gt;&lt;b&gt;length&lt;/b&gt;&lt;/font&gt;&amp;nbsp;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;obj&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#ff8b00"&gt;regExp&lt;/font&gt;.&lt;font color="#458b73"&gt;exec&lt;/font&gt;( allText );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;NOTES:&lt;br /&gt;&lt;br /&gt;All those statements that reference "carretIndex" grab a chunk of the text, starting 100 characters before the cursor position and running to the cursor position. (Unless there's less than 100 characters of text, in which case the chunk is from the beginning to the cursor.) I do this because if the text gets long, I don't want -- or need -- to check all of it. 100 characters is probably overkill, but it allows the user to type @supercalifragilisticexpialidocious if he so chooses.&lt;br /&gt;&lt;br /&gt;In this statement...&lt;br /&gt;&lt;br /&gt;input.setTextFormat( tfDefault, allText.length-1, allText.length  );&lt;br /&gt;&lt;br /&gt;...I make sure the text after the cursor changes back to its default black, so that non @words won't be red.&lt;br /&gt;&lt;br /&gt;Finally, I loop through all the RegExp matches and colorizes them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-6902788270237479648?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/6902788270237479648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/05/colorizing-text-as-you-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6902788270237479648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6902788270237479648'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/05/colorizing-text-as-you-type.html' title='colorizing text as you type'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_eeOpXM9pWmE/SiLKfaV8hyI/AAAAAAAAAA4/apAl1NnWVp4/s72-c/words.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-3687999341640689114</id><published>2009-05-29T13:58:00.000-07:00</published><updated>2009-05-29T14:41:30.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript trace firebug console debug log firefox'/><title type='text'>my replacement for trace()</title><content type='html'>When debugging a Flash app online, it always sucks that you can't use trace(). There are all sorts of tricks to get around this, including the great &lt;a href="http://demonsterdebugger.com/"&gt;DeMonster Debugger&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;As much as I like such tools, I've always wished for something simpler. Something like trace() -- but a trace() that works in the browser. Recently, my wish was granted. I learned that Firebug's console accepts logs from Flash. (&lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; is a must-have Firefox plugin for web developers.) &lt;br /&gt;&lt;br /&gt;Firebug has a Javascript API which contains a function called console.log. That's great, because Flash can call JS functions, via ExternalInterface.call(functionName,param[s]).&lt;br /&gt;&lt;br /&gt;So, all you have to do to send a message from Flash to Firebug is...&lt;br /&gt;&lt;br /&gt;1. make sure that the allowScriptAccess parameter is set to "always" in the html page's object and embed tags (it's often set to "sameDomain" by default). &lt;br /&gt;&lt;br /&gt;2. In the Actionscript, import Flash.external.ExternalInterface (works in AS2 and AS3).&lt;br /&gt;&lt;br /&gt;3. When you want to "trace" to the console, type something like this: ExternalInterface.call( "console.log", "hello, world" );&lt;br /&gt;&lt;br /&gt;That's great, but I don't want have to type something that long every time I want to run a quick trace-like action. So I made this little utility function (below). Feel free to use it. Just...&lt;br /&gt;&lt;br /&gt;1. Copy it into the folder that contains the fla.&lt;br /&gt;&lt;br /&gt;2. Make sure allowScriptAccess is set to "always" in the HTML's object and embed tags.&lt;br /&gt;&lt;br /&gt;3. When you want to "trace," just call log(param1, param2, ... paramN);&lt;br /&gt;&lt;br /&gt;The cool thing is that log() calls trace() internally, so you can use it for both local development and in-browser testing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;NOTE: with one angry client of mine, the ExternalInterface.call() method cased JavaScript errors on their site. So before going live, I recommend you comment out the final line in the log() function and recompile.&lt;/span&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#458b73"&gt;package&lt;/font&gt;&amp;nbsp;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#458b73"&gt;import&lt;/font&gt;&amp;nbsp;&lt;font color="#ff8b00"&gt;flash&lt;/font&gt;.&lt;font color="#ff8b00"&gt;external&lt;/font&gt;.&lt;font color="#008b00"&gt;&lt;b&gt;ExternalInterface&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#458b73"&gt;public&lt;/font&gt;&amp;nbsp;&lt;font color="#458b73"&gt;function&lt;/font&gt;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;log&lt;/b&gt;&lt;/font&gt;( &lt;font color="#b02f60"&gt;&lt;b&gt;message&lt;/b&gt;&lt;/font&gt;&amp;nbsp;: *, ... rest ) : &lt;font color="#cc0000"&gt;void&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;s : &lt;font color="#b02f60"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#4a6f8b"&gt;&amp;quot;&amp;quot;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;&amp;nbsp;: &lt;font color="#b02f60"&gt;&lt;b&gt;Array&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= rest as &lt;font color="#b02f60"&gt;&lt;b&gt;Array&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;.&lt;font color="#008b00"&gt;&lt;b&gt;unshift&lt;/b&gt;&lt;/font&gt;( &lt;font color="#b02f60"&gt;&lt;b&gt;message&lt;/b&gt;&lt;/font&gt;&amp;nbsp;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;trace&lt;/b&gt;&lt;/font&gt;.&lt;font color="#b02f60"&gt;&lt;b&gt;apply&lt;/b&gt;&lt;/font&gt;( &lt;font color="#b02f60"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;, a );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#b02f60"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;( &lt;font color="#b02f60"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i : &lt;font color="#b02f60"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;= &lt;font color="#cc0000"&gt;0&lt;/font&gt;; i &amp;lt; a.&lt;font color="#008b00"&gt;&lt;b&gt;length&lt;/b&gt;&lt;/font&gt;; i++ )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s += &lt;font color="#008b00"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;[ i ].&lt;font color="#008b00"&gt;&lt;b&gt;toString&lt;/b&gt;&lt;/font&gt;() + &lt;font color="#4a6f8b"&gt;&amp;quot; &amp;quot;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b00"&gt;&lt;b&gt;ExternalInterface&lt;/b&gt;&lt;/font&gt;.&lt;font color="#b02f60"&gt;&lt;b&gt;call&lt;/b&gt;&lt;/font&gt;( &lt;font color="#4a6f8b"&gt;&amp;quot;console.log&amp;quot;&lt;/font&gt;&amp;nbsp;, s );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are a few of things worth noting about this function: first of all, it's in a package by itself -- it's not part of a class. Normally, I think of that as a no-no, but in this one case, I let myself do it. I want to be able to type just log(), not Debug.log() or something like that. But if the stand-alone function offends you, just pop it into a class.&lt;br /&gt;&lt;br /&gt;log() accepts an arbitrary number of parameters, via the relatively obscure structure ...rest. So you can call it like this log("hello"); like this: log("hello", true); like this: log("hello", true, 45.6, [1,2,3], mySprite.x); etc.&lt;br /&gt;&lt;br /&gt;In the above examples, "hello" would be stored in the message parameter and the rest of the parameters would be stored in rest. rest is an Array-like object, but it's not actually an Array. That's a problem, because the Function.apply() method, which I use to call trace(), needs an Array. That why I create the a Array and set it to rest as Array(). Then I push message onto the beginning of it, so that all the parameters are in one big Array.&lt;br /&gt;&lt;br /&gt;That allows me to call trace.apply( this, a ). The Function.apply method isn't very well known. It allows you to call a function and use an Array as that function's list of parameters. For instance, the following two snippets have the same effect:&lt;br /&gt;&lt;br /&gt;SNIPPET 1:&lt;br /&gt;trace(1, 2, 3);  &lt;br /&gt;&lt;br /&gt;SNIPPET 2:&lt;br /&gt;var a : Array = [1, 2, 3];&lt;br /&gt;trace.apply( this, a );&lt;br /&gt;&lt;br /&gt;(The first parameter to apply allows you to apply the function to a specific object. It's not important here, so I just used "this.")&lt;br /&gt;&lt;br /&gt;Finally, for Firebug's console, I concatenate all the a values into a space-separated string and output them using the Console.log JS function. If you comment out the last line, log() will still work for local traces but it will no longer try to call a JS function on the web page housing the swf.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-3687999341640689114?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/3687999341640689114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/05/my-replacement-for-trace.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3687999341640689114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3687999341640689114'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/05/my-replacement-for-trace.html' title='my replacement for trace()'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-7500012177441932120</id><published>2009-05-29T12:57:00.001-07:00</published><updated>2009-05-29T13:03:01.175-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='regexp filename actionscript'/><title type='text'>grab just the filename without the extension</title><content type='html'>var filename1: String = "monster.jpg";&lt;br /&gt;var filename2: String = "big.fat.hippo.flv";&lt;br /&gt;&lt;br /&gt;filename1 = filename1.replace( new RegExp( "(.*)\.(.*)", "g" ), "$1" );&lt;br /&gt;filename2 = filename2.replace( new RegExp( "(.*)\.(.*)", "g" ), "$1" );&lt;br /&gt;&lt;br /&gt;trace(filename1); //monster&lt;br /&gt;trace(filename2); //big.fat.hippo&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-7500012177441932120?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/7500012177441932120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/05/grab-just-filename-without-extension.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/7500012177441932120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/7500012177441932120'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/05/grab-just-filename-without-extension.html' title='grab just the filename without the extension'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-6567693790900719707</id><published>2009-05-29T12:23:00.001-07:00</published><updated>2009-05-29T13:03:30.598-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript scale'/><title type='text'>Constrain Proportions</title><content type='html'>Here's a really simple solution that I couldn't figure out for a long time: say you need to downsize an image so that the width changes to 80 pixels. You want to change the height, too, so that the image stays in proportion, but by how much should you change it?&lt;br /&gt;&lt;br /&gt;I actually figured out a complex way to calculate the height, but then it hit me that there's a really simple way to do it:&lt;br /&gt;&lt;br /&gt;myImage.width = 80;&lt;br /&gt;myImage.scaleY = myImage.scaleX;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-6567693790900719707?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/6567693790900719707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/05/constrain-proportions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6567693790900719707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/6567693790900719707'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/05/constrain-proportions.html' title='Constrain Proportions'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206051964260112891.post-3328988602428906767</id><published>2009-05-29T11:54:00.000-07:00</published><updated>2009-07-20T12:24:51.336-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actionscript bugs'/><title type='text'>Dumb Bugs</title><content type='html'>Hi. Welcome to Grumbleblog. &lt;br /&gt;&lt;br /&gt;I'm a programmer, and I currently code mostly in Actionscript 3.0, Flash's language (a sister tongue to JavaScript). In this blog, I will post info about Actionscript, other languages, and various technical topics that are too arcane for my &lt;a href="http://wscmonster.blogspot.com/"&gt;regular blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To start the ball rolling, here's a list of dumb mistakes I frequently make when I'm coding. Though I'll come back here and update the list (as I catch more mistakes), the list will probably only useful to me. &lt;br /&gt;&lt;br /&gt;However, I recommend that you make a similar list for yourself. It's useful when you're stuck. Before you start pounding your head against the wall, take a deep breath and check your list. &lt;br /&gt;&lt;br /&gt;MY COMMON BUGS&lt;br /&gt;&lt;br /&gt;- typing function when I mean var and vice versa.&lt;br /&gt;EXAMPLE: public var killMyself() : void...&lt;br /&gt;&lt;br /&gt;- omitting the underscore prefix on private variables (my convention).&lt;br /&gt;EXAMPLE: private var highscore instead of private var _highscore&lt;br /&gt;&lt;br /&gt;- forgetting to make classes public (when they should be).&lt;br /&gt;EXAMPLE: class ISuck... instead of public class ISuck...&lt;br /&gt;&lt;br /&gt;- messing up close curly braces.&lt;br /&gt;EXAMPLE: if (true) { while(true) { trace(true) } //missing a close }&lt;br /&gt; &lt;br /&gt;- omitting the word "function." &lt;br /&gt;EXAMPLE: private addTwo()... instead of private function addTwo()...&lt;br /&gt;&lt;br /&gt;- omitting a var's type.&lt;br /&gt;EXAMPLE: private var name = "Bob" instead of private var name : String = "Bob";&lt;br /&gt;&lt;br /&gt;- leaving off var in for loops.&lt;br /&gt;Example: for ( i : int = ... instead of for ( var i : int =...&lt;br /&gt;NOTE: I'm especially prone to this with for-in loops.&lt;br /&gt;NOTE: I also sometimes leave off the type: &lt;br /&gt;for (var i = 0... instead of (var i : int = 0...&lt;br /&gt;&lt;br /&gt;- forgetting to call new on classes that are sub objects:&lt;br /&gt;EXAMPLE: o.point = {x:10,y:20}; instead of...&lt;br /&gt;o.point = new Point();&lt;br /&gt;o.point = {x:10,y:20};&lt;br /&gt;&lt;br /&gt;- adding an event listener to a Loader to test for load completion. I should be attaching it to loaderInstance.contentLoaderInfo instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206051964260112891-3328988602428906767?l=grumblecode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://grumblecode.blogspot.com/feeds/3328988602428906767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://grumblecode.blogspot.com/2009/05/dumb-bugs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3328988602428906767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206051964260112891/posts/default/3328988602428906767'/><link rel='alternate' type='text/html' href='http://grumblecode.blogspot.com/2009/05/dumb-bugs.html' title='Dumb Bugs'/><author><name>Marcus</name><uri>http://www.blogger.com/profile/10199110239609732534</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://grumblebee.com/doodles/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
