Hack 75 Strict Typing and Casual Scripters 
ActionScript 2.0 introduces strict typing to
check for incorrect datatypes. Strict typing can help motion graphics
developers spend less time debugging and more time being
creative.
ActionScript 2.0 introduces strict
typing to detect datatype mismatches at compile time. Should you use
strict typing if you're a motion graphics scripter
and not a hard-core application developer creating object-oriented
programs using classes? The answer is a resounding
"yes." Motion graphics is
predominantly about speed and responsiveness, and all developers want
to spend less time debugging and more time being creative. Strict
typing lets you perform less runtime checking, which improves
performance, and the compile-time checks catch potential errors that
would cause silent failure in Flash MX.
So you get better, more robust code using ActionScript 2.0
type checking,
even if your code is brief and doesn't use
object-oriented techniques. The additional type checking makes it
more likely your code will work correctly once it compiles
successfully, and there is no runtime performance hit [Hack #100] .
How Strict Typing Helps
Let's
have a look at how to implement some ActionScript 2.0 code and how
strict typing helps when scripting motion graphics.
function makeDot(clip:MovieClip):Void {
// Make a dot within clip
clip.lineStyle(10, 0x0, 100);
clip.moveTo(0, 0);
clip.lineTo(1, 0);
}
function mover( ):Void {
// Move the dot
this.sX = checkLimits(this.sX, this._x, 0, 550);
this.sY = checkLimits(this.sY, this._y, 0, 400);
this._x += this.sX;
this._y += this.sY;
}
function checkLimits(speed:Number, limit:Number,
low:Number, high:Number):Number {
// Reverse direction when the dot hits an edge of the screen
if ((limit < low) || (limit > high)) {
return -speed;
} else {
return speed;
}
}
var ball:MovieClip;
for (var i:Number = 0; i < 100; i++) {
ball = this.createEmptyMovieClip("dot" + i, i);
ball._x = Math.random( ) * Stage.width;
ball._y = Math.random( ) * Stage.height;
ball.onEnterFrame = mover;
ball.sX = Math.random( ) * 8 + 2;
ball.sY = Math.random( ) * 8 + 2;
makeDot(ball);
}
Notice that var ball:MovieClip; declares the
ball variable to be an instance of the
MovieClip class (this is synonymous with saying
that ball is of type
MovieClip because a class declaration
effectively defines a custom datatype of the same name). Specifying
ball's type as
MoveClip tells the compiler that the variable
must contain a movie clip reference. We later use the
ball variable to store a reference to the clip
created at runtime with createEmptyMovieClip( ),
such as clips dot0, dot1, and
so on.
Notice that the datatype is specified after a colon, and whenever you
define a datatype for a variable, the variable must be preceded by
the var keyword.
If we try to assign a value that is not a movie clip reference, such
as:
ball = 0;
ball = "dot+i";
the Flash compiler displays a type mismatch in the Output panel.
Fixing it during authoring is easy and fast, whereas omitting the
type checking would leave us staring at a blank Stage at runtime,
wondering where the problem might lie.
Notice in the preceding example that the functions and event handlers
are also typed. A function that doesn't return any
value should be given a return type of Void (with
a capital "V"):
function myName( ):Void {
// Do stuff
};
If the preceding function returns a value, which it
shouldn't, Flash displays an error at compile time.
A function that accepts arguments and returns a value is written like
this:
Function myName(argument:argType):returnType {
// Do stuff
return someValue;
};
If we try to pass it an argument that is of the wrong datatype or if
it returns the wrong datatype (i.e., if someValue
isn't of the datatype specified by
returnType), Flash again provides a
compile-time error.
Using strict type checking helps the Flash compiler catch many bugs
that would have caused runtime problems in Flash MX. ActionScript 2.0
strict typing helps to confine errors to one code block (such as a
function or event handler) to prevent errors from propagating to
other code that calls the problematic code.
Limitations of Strict Typing
Strict
typing can't be quickly and easily used in all
cases. Let's look at some of the limitations of
compile-time type checking.
Dynamic properties are not type checked
Notice that in the preceding example, ball.sX and
ball.sY are specified without a datatype. You
cannot use the var keyword when you attach
custom properties to a clip dynamically at runtime. Not being able to
use var also means that you
can't specify their datatype. Furthermore, because
an untyped variable is allowed to be of any datatype, the Flash
compiler wouldn't complain about the following (even
though we intend ball.sX to hold a number not a
string):
ball.sX = "cat";
Even though ball.sX is eventually accessed as
this.sX inside the mover( )
function and passed to the checkLimits( )
function as a parameter named speed,
where it is strictly typed as Number,
Flash's compile-time validation
can't detect such indirect errors. An untyped
variable passes through all checks with no errors.
If you want to use strict typing to validate the datatype of
properties, you have to create a custom class. You can then define
the type of each class property or instance property within the class
definition. For example, you can place this code in an external
Ball.as file to create a custom
Ball class that subclasses the
MovieClip class:
// This ActionScript 2.0 code must go in an external Ball.as file
class Ball extends MovieClip {
var sX:Number;
var sY:Number;
}
Then, revising the earlier code example, you can declare the
ball variable to be of type
Ball instead of type
MovieClip:
var ball:Ball;
Because of the class definition, Flash will perform type checking on
instance properties such as ball.sX and
ball.sY.
Conditional statements confuse type checking
Flash supports only compile-time type checking, so it does not run
the code when it performs type checking. Therefore, it cannot detect
cases involving return statements within
conditional expressions. If an if statement is
structured as follows, the checkLimits( )
function won't return a value even though its return
datatype is specified as Number:
function checkLimits(speed:Number, limit:Number,
low:Number, high:Number):Number {
if (false)) {
return -speed;
}
};
But Flash checks only the datatype of the expression following the
return keyword, in this case
-speed, and the preceding code does not cause a
compile-time error.
Final Thoughts
ActionScript 2.0 provides type checking unavailable in ActionScript
1.0, without affecting runtime performance or complaining about
untyped variables (i.e., it won't choke on legacy
ActionScript 1.0 code that hasn't been updated to
ActionScript 2.0). Type checking helps you write correct, robust code
by catching errors you might otherwise miss.
Although ActionScript 2.0 doesn't perform type
checking at runtime and author-time type checking
can't be quickly implemented in all cases, using
type checking whenever possible saves scripters of all levels
considerable time and aggravation.
|