oh how i hate adoring you actionscript3
Coming off an insane project done entirely in PHP, I’ve been using my downtime to drown myself in AS3. Anyone who has spent any amount of time dealing with PHP can feel me when I say that moving to any language approaching some sense of sanity in its design, is a feeling not unlike being thrown a life preserver from God.
Really it’s that bad. Even though PHP is currently my bread and butter – the less time I spend with it, the more wholesome I feel inside. And, try as I might to maintain some sense of tool agnosticism, and despite my accomplishments with making PHP do some pretty tricked out shit, I still feel like I’ve been reading children’s books written by dyslexics for 6 months straight. You know your language might be crappy when the following is true:
$goddamnit='false'; if ((!$goddamnit) && ($goddamnit==0) && ($goddamnit==false)) echo 'this pretty much blows.';
So we launched the site and we’ve hired enough smart people to take on more of the PHP, leaving me some time to do some R&D and to take a break from PHP, if not for just a few weeks. I’ve spent this precious time diving head first into Flex and ActionScript 3.
At first, it was joy.
No more $ signs?? Sign me up! Typed variables?! Namespaces?? F*cking fantastic!
You see, I’m one of those weird guys who grew up on Turbo Pascal and Borland Delphi (actually, my first language was HyperTalk/SuperTalk via SuperCard on the Mac, but I digress). Pascal is one of the most anal languages in existence, but the beauty of it is that the code looks and reads like pseudo-code and because of this is almost completely self-documenting. Suffer:
unit Freelbl;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs;
type
TFreeLabel = class(TGraphicControl)
private
{ Private declarations }
procedure WMERASEBKGND(var msg:TWMERASEBKGND); message WM_ERASEBKGND;
procedure CMFONTCHANGED(var msg:TMsg); message CM_FONTCHANGED;
procedure CMTEXTCHANGED(var msg:TMsg); message CM_TEXTCHANGED;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(Aowner:TComponent); override;
procedure Paint; override;
published
{ Published declarations - Inherited from ancestor }
property Caption;
property Align;
property Color;
property Font;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TFreeLabel]);
end;
constructor TFreeLabel.Create(Aowner:TComponent);
begin
inherited Create(Aowner);
ControlStyle := [csOpaque];
end;
procedure TFreeLabel.Paint;
var t:TBitmap;
r:TRect;
Text:array[0..255] of Char;
begin
T:=TBitmap.Create;
t.width:=width;
t.height:=height;
with t.canvas do
begin
brush.color:=self.color;
r:=Rect(0,0,width,height);
fillrect(r);
font:=self.font;
StrPCopy(Text, Caption);
DrawText(t.canvas.Handle, Text, StrLen(Text), R, DT_CENTER or
DT_VCENTER or DT_WORDBREAK);
end;
canvas.draw(0,0,t);
t.free;
end;
procedure TFreeLabel.CMFONTCHANGED(var msg:TMsg);
begin
invalidate;
end;
procedure TFreeLabel.CMTEXTCHANGED(var msg:TMsg);
begin
invalidate;
end;
procedure TFreeLabel.WMERASEBKGND(var msg:TWMERASEBKGND);
begin
{ Since we blot out the background in the paint method, there is no need
to be redundant. }
msg.result:=1;
end;
end.
This is some really ancient shit, circa 93 or something. Anyways, it should make some sense if you know the basics of pascal. It’s an incredibly basic Windows control that buffers itself to a bitmap to reduce flicker (a problem in Windows 95). Note how neatly organized the class definition is, the separation of interface and implementation. All good stuff if you like to type a lot. I’m kind of lazy, so I eventually made my way to the curly brace languages and haven’t really looked back since.
So maybe you can understand how moving from the murky junk that is PHP to something more structured like ActionScript 3 is sort of like a home coming.
Ok, so not quite coming home. More like visiting an old house you lived in, but with completely new furniture and occupants. And, even though it’s different, it’s somehow the same. On top of this I was also diving into MXML which is pretty similar to something I started but never finished a long ass time ago. You can read about it here.
But, as I got into it deeper, I noticed a few things that had me cursing at the language:
Lack of private/protected/internal constructors. This one had me confused as it seemed like a glaring omission. Somehow they worked in metadata for classes and properties (what we call attributes in C#) but missed one of the more fundamentals. Why is this a big deal? I would argue that Singletons are the single most oft repeated pattern in modern development. To implement a singleton in AS3 – properly – requires some fugliness and adds a lot of typing. Boo typing!
Destructors. Listen, if you really intend to use this for an RIA, specifically a media heavy RIA, you are going to have to take on some resource management less your ship spring a leak and sink. Debugging Flash is still a bitch in comparison to debugging desktop apps, the event handling clouding it even further.
Method overloading. I know, you can fake it, but it would be sensational to have.
Events Everywhere! The lack of synchronous operation is a bit of a drag. I understand why it is the way it is, but because of it you can end up with code that’s the OO version of GOTO statements aka spaghetti code. For example, it’s a real pain when you’re trying to deal with a web service API. It’s kludgey to have to write all these event handlers and hack together a system that blocks the application going any further until the event handler is called. It’s a cheap version of threading and it’s cumbersome. I know, I know, this isn’t the fault of the language, it’s the design of the framework, but it’s still a major pain.
Properties Don’t get me wrong, I’m glad AS3 has them. PHP doesn’t, but you can fake it with the __get and __set “magic” methods (why a language has “magic” methods is beyond me). I just don’t dig how they’re declared. To me this is more succinct:
public class foo
{
private var _bar:String="wh00t";
public property bar:String get _bar set setBar;
private function setBar(val:String):void
{
_bar=val;
}
}
Again, it’s that quirky background in Pascal, but I prefer the implementation of my getters or setters to be separated visually from my variable/property declarations. I would also like to be able to specify direct access to the variable instead of writing a stub get or set function.
So we’re doing pretty good so far, only 4 things that annoy me and all of them survivable – although the event driven stuff can be quite maddening at times.
