(Or, one of the many things that ticks me off about Actionscript 3...)
Seems like every time I talk about Actionscript, I'm ranting about something or other that's just ticking me off. I have to start posting about the things I love about it. [ed. I started this post a long time ago and haven't gotten around to finishing it until now. sue me.]
Well, not tonight [ed. today]. Soon, though, I promise.
One of the cool additions to AS 3 is the const keyword. Compile time constants are a beautiful thing. And right off the bat, Adobe started using constants all over the place. In many places, as simulated enums. This is cool, this is good, very excellent.
The big problem is that it misses the point. Enums aren't simply a way of ensuring that you don't make a type-o, letting the compiler throw an error at you because you once again incorrectly spelled "eneterFrema" (yes, I know you spell "spelled" s-p-e-l-l-e-d, I'm employing some sort of literary device, can't remember which, deal with it). Enums are there to make you code a) easier to read and b) easier to write.
I'll illustrate with an example:
GradientGlowFilter (well, actually, you can go with pretty much any bitmap filter on this one, but I'm going to use GGF for a few reasons: firstly, it doesn't include BitmapFilter in it's name, secondly, it's the one I ran into this particular issue with, so there).
The gradient glow filter constructor has the following prototype:
-
GradientGlowFilter(distance:Number = 4.0, angle:Number = 45,
-
colors:Array = null, alphas:Array = null, ratios:Array = null,
-
blurX:Number = 4.0, blurY:Number = 4.0, strength:Number = 1,
-
quality:int = 1, type:String = "inner", knockout:Boolean = false)
Specifically, I'm looking at the "type" parameter. It's typed as a string, but it only has three possible values, namely, BitmapFilterType.FULL, BitmapFilterType.INNER, or BitmapFilterType.OUTER. You'll notice the default value for the parameter in the constructor above is the string literal "inner". That should have been, at the least, BitmapFilterType.INNER. That would get across (in applications like FlashDevelop and, yes, even in the Flash IDE [ed. you don't actually use the Flash IDE to write code, do you? Seriously...]) that, even though it's using constants and not enums, the value must be one of the constants on the BitmapFilterType class. Same holds true for the quality parameter. It's typed as number, default value is 1, and it needs to be a member of the BitmapFilterQuality class.
Moving to enums would solve this in two ways. For starters, it would be type-safe (eg: if you tried to pass a string, it would break at compile time). And it would be self-documenting, in that by looking at the method prototype you would immediately know what your possible values are and where to find the enum. (Never mind that naming the parameter "type" is ridiculously unhelpful...at least naming it bitmapFilterType would have cleared up what the parameter is there for.)
The truth is, these aren't huge issues, and one could argue that the additional overhead of using an enum-type of class (a la my examples posted previously) adds overhead that isn't absolutely necessary, in the form of properties, etc), but for my money the developer ease of use and clarity far outweighs that (I can't imagine there would be a huge performance bottleneck by having constants that are instances of a class instead of raw strings).
To me, the constructor prototype for this should have been:
-
GradientGlowFilter(distance:Number = 4.0, angle:Number = 45,
-
colors:Array = null, alphas:Array = null, ratios:Array = null,
-
blurX:Number = 4.0, blurY:Number = 4.0, strength:Number = 1,
-
quality:int = BitmapFilterQuality.LOW, bitmapFilterType:String = BitmapFilterType.INNER,
-
knockout:Boolean = false)
Sure, I can look at the documentation and get the answer in seconds, but that's still seconds where I'm second guessing myself.
The other example I was going to bring up was event types (eg: new Event( Event.ENTER_FRAME ) - I finally saw an example last week of using string names for events where it actually made sense to use strings, as opposed to a fully-typed event model, but never mind that). My biggest problem with the implementation, truth be told, is the lack of consistency with where the event type constants are housed (eg. where are the packages for event types? why is ACTIVATED a constant on the Event class, but ACTIVITY is a constant on the ActivityEvent class? Why aren't ADDED and ADDED_TO_STAGE on the DisplayEvent class (which doesn't exist, ttbomk)? why are they all over the place? the list goes on...).
My point with all this is that time and time again, the Actionscript BCL does developers gross injustice by not implementing API's that are consistent and usable. Adobe should make it mandatory that every developer on the team have a copy of Framework Design Guidelines sitting on their desks.
I should probably say, again, that I really do love Flash and where it's going (and where it's been), but as it matures, these are the issues that are going to differentiate it from the other offerings (Silverlight? maybe, I don't know...they do really come at it from different angles, but hey...). And that's not me saying the Silverlight API's are perfect (truth be told, I haven't done much with them, so I can't really offer an opinion there).
Allright. Enough of a rant. Next time, I'm going to scream about the Sound API. Argh. Lovely capabilities. Scary API. Seriously. Scary.
Seeya next time, on J's Bitchings About Things Not Many Other People Care About (But, In His Opinion, They Should).
Share me:
These icons link to social bookmarking sites where readers can share and discover new web pages.