Vector vs Array and proper code guards

Consider the following code-snippet (don’t ask how I got it!):

private function process(dataResponse:Array):void
{
	if (!dataResponse || !dataResponse.length)
	{
		return;
 	}

	 var errCode:uint = dataResponse[0] as uint;
	 switch (errCode)
 	{
		 case ERR_OK:
			/** handle happy flow, update model whatever **/
 			break;
		case ERR_ONE:
			/** handle error type one show err message etc **/
			break;
		case ERR_TWO:
			/** handle error type two show err message etc **/
		 	break;
	}
}

If by any chance dataResponse[0] does not exist, the conversion to unsigned integer evaluates to undefined. Then the assignment of an undefined value to the uint variable produces a nice 0, which happens to be your happy flow handle case in the given scenario. So you got yourself a nice little bug which could mess up your whole application …

One way to go about it is to actually test the first element of the array exist and only after that proceed with the switch statement.

if (!dataResponse[0])
{
	throw new Error("Invalid error code");
	/** or handle the error in a different fashion **/
}

However, a different possible approach is to use a Vector instead of an Array. That would solve many of the problems from the beginning. An Array allows you to insert an element whatever position you want inside, even though the previous positions are still empty.

var dataResponse:Array = [];
dataResponse[2] = 3;

The guard test from the above code (for the array not being null and having a valid length) will pass since there is valid Array instance and length property evaluates to 3. This leads to the situation of having a valid OK value produced under the wrong circumstances. Pretty difficult to debug since there is no error message. On the other hand, having a Vector instead forces you to populate it properly either by using the push() method or making sure that every element is filled starting from the first one. In other words this code

var var dataResponse:Vector.<uint> = new Vector..<uint>;
dataResponse[2] = 3;

will yield the following error RangeError: Error #1125: The index 2 is out of range 0. It will be easy to see that there is something wrong with your data.

The aforementioned guard will work just fine now and you can finally have the assignment for the switch statement.

var errCode:uint = dataResponse[0];

The element is guaranteed to be an uint so no more casting is required. And the new version of the code:

private function process(dataResponse:Vector.<uint>):void
{
	if (!dataResponse || !dataResponse.length)
	{
		return;
	}
	
	var errCode:uint = dataResponse[0];
	switch (errCode)
	{
		case ERR_OK:
			/** handle happy flow, update model whatever **/
			break;
		case ERR_ONE:
			/**handle error type one show err message etc **/
			break;
		case ERR_TWO:
			/**handle error type two show err message etc **/
			break;
	}
}

So use Vector class instead of Array whenever you can (vector is usually faster anyway) and happy flashing/flexing!

P.S.
Vector class is available starting with the version 10 of the Flash Player.

Leave a Reply

Your email address will not be published. Required fields are marked *

*