moock.org is supported in part by


July 23, 2004

in praise of type checking

if you haven't seen the light of actionscript 2.0's datatype checking yet, here's one little demo to help win you over. there are two errors in the following code. can you spot them?

  private function setText (theText:String):Void {
    resetAssetClip();
    var tf:TextField = assetClip.createTextField("t", 
                              assetDepth, 0, 0, width, 0);
    tf.multiline = true;
    tf.wordWrap  = true;
    tf.autoSize  = left;
    tf.html      = true;
    tf.htmlText  = theText;  
  }

if you're a *real* keener, you might have spotted one error: the autoSize property should be a string, as in "left", not left. but you have no way to find the other error: the above setText() method refers to the property "assetClip", but that property doesn't exist because i changed its name from "assetClip" to "asset_mc". i made the change for consistency with other property names in my class, but i forgot to update the setText() method to use the new name. so the above attempt to create a text field fails.

without actionscript 2.0's type checking i might have spent 20 minutes or more trying to fix the above code. with some tests, i would have had to narrow down the assetClip naming problem, then i would have had to figure out why my text field wasn't resizing properly. without knowing the TextField api by heart, i'd probably have spent quite a while figuring out that the value, left, should really be the string, "left".

*with* type checking, the compiler tells me about both of the above errors for free, in less than 1 second. it even tells me where the error is and what went wrong:

**Error** Item.as: Line 50: There is no method with the name 'assetClip'.
var tf:TextField = assetClip.createTextField("t", assetDepth, 0, 0, width, 0);

**Error** Item.as: Line 53: There is no property with the name 'left'.
tf.autoSize = left;

bam. i just saved somewhere in the range of 5-20 minutes tracking down errors. now i can move on with my code and be more productive. all hail actionscript 2.0 type checking.

incidentally, if i had made a typo in the string value "left" above--something like "lfet"--no error would have occurred. the type checker can only report problems with datatypes not with the contents of a string. for that reason, the possible values of TextField.autoSize should really be defined as static properties, such as TextField.AUTOSIZE_LEFT. that way if you specify TextField.AUTOSIZE_LFET the compiler can tell you about your mistake. i'm hoping that in the future the flash player api will move more towards properties and fewer "magic" strings and "magic" numbers (a "magic" value is a hardcoded primitive value that has some important meaning for a class but, despite that importance, isn't exposed formally through a property or method.)

back to the erroneous method. let's suppose i now fix the errors, and the method looks like this:

  private function setText (theText:String):Void {
    resetAssetClip();
    var tf:TextField = asset_mc.createTextField("t", 
                              assetDepth, 0, 0, width, 0);
    tf.multiline = true;
    tf.wordWrap  = true;
    tf.autoSize  = "left";
    tf.html      = true;
    tf.htmlText  = theText;  
  }

can you spot the third error? The MovieClip.createTextField() method doesn't return the TextField instance it creates (no matter how much we wish it did!). so the value of tf is undefined when the above method runs. how long would it have taken you to figure that out with simple testing? no matter how fast you are, the answer is "longer than the 1 second it took the compiler". again, because i've specified the datatype of tf as "TextField", the compiler can warn me that createTextField() isn't returning what i expect or want it to. here's how the compiler warns me:

**Error** Item.as: Line 50: Type mismatch in assignment statement: found Void where TextField is required.
var tf:TextField = asset_mc.createTextField("t", assetDepth, 0, 0, width, 0);

man i owe the compiler a beer. here's the corrected, working version of the method:

private function setText (theText:String):Void {
  resetAssetClip();
  asset_mc.createTextField("t", assetDepth, 0, 0, width, 0);
  var tf:TextField = asset_mc.t;
  tf.multiline = true;
  tf.wordWrap  = true;
  tf.autoSize  = "left";
  tf.html      = true;
  tf.htmlText  = theText;  
}

sweet. once you get used to this kind of helping hand, you'll wonder how you ever lived without it.

--
(if you want more of this kind of discussion, i blab on like this for 500 pages in essential actionscript 2.0...)

Posted by moock at July 23, 2004 01:31 PM