Monday, July 2, 2007

ActionScript 3 isNaN is BaD

A primary rule of my programming style is to keep things positive whenever possible.  For example it always clearer to test for things to be equal than to test for them to be not equal.  So I'm not surprised there are many discussions about the ActionScript isNaN function on the Internet.  NaN stands for "not a number".  Its roots go deeper than ActionScript.  It is self-evident why the term was coined and equally predictable to be a subject of confusion.

However, the function's negativity can only be charged with creating "bad vibes" in the misdeeds mentioned in this post.  The following comes from the Adobe documentation: 

 

The last two table rows in the documentation pass strings to the isNaN function.  However, I get a fatal compile error when I try to do this.  The same documentation clearly specifies the argument type is "Number".  The editor's "Intellisense?" (I don't know what Adobe calls it) says the argument is a "Number".

But I can find plenty of examples on the Internet showing string arguments.  I think some of these examples may be explained by the fact that they don't specify the type in the var declaration.  When I do this, I get a compiler warning.  I wouldn't post an example that produced a compiler warning, at least without pointing it out, but maybe I'm in the minority.

Other examples may be about earlier versions of ActionScript or maybe beta versions.  It's sometimes hard sort these things out.  I am using Flex Builder 2 and have also tried this with the Flex Builder 3 beta.  I got around the warning message by using the asterisk as the variable type.  I don't like using an asterisk as a workaround, but in this case I think that is how the argument is internally defined.  This is because the function actually works when I pass a string to the function.

I really only wanted to write a function to determined if a string contained a valid number.  The following example works.  Notice the asterisk in the "for each" statement.

<?xml version="1.0" 

encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    creationComplete="onCreationComplete()"
    >
    <mx:TextArea
        id="Text1"
        height="400"
        />
    
    <mx:Script>
        <![CDATA[
        // -----------------------------------------
        // onCreationComplete
        // -----------------------------------------

        private function onCreationComplete
            ()
            :void
        {
            var lvString:String = "";
            
            for each( var lvValue:*
                  in ["5", "A", "-1", "-.7", "*" ] )
                lvString += lvValue
                          + ": NaN is "
                          + isNaN( lvValue ).toString()
                          + "\n";
            
            Text1.text += lvString;

        } // onCreationComplete
        ]]>
    </mx:Script>
    
</mx:Application>

Text1 contains the following when the example is run:

5: NaN is false
A: NaN is true
-1: NaN is false
-.7: NaN is false
*: NaN is true

This has been a minor distraction while developing an example program for a new post on my series of Sorting XML which I hope to have ready this week.

2 comments:

Anonymous said...

Thank you! We're porting from Java to Actionscript right now and this was a huge pain.

Anonymous said...

just use this:

function IsNumber(value:object):boolean {
return !isNaN(Number(value));
}