NaN and 0

I have a question of how to handle parameters of type Number.
This code…


function myFunc(i:Number = NaN):void
{
    trace(i);
    if (isNaN(i)) trace("Not a number!");
    else trace("Is a number!");
}

function getUnknownValue():* {
    return null;
}

myFunc(0);
trace("-----------------");
myFunc(getUnknownValue());

Outputs this…


0
Is a number!
-----------------
0
Is a number!

In myFunc, in both instances i is converted to 0. If I wanted different behaviour for 0 as I did for null, how can myFunc tell whether what was passed is originally a number or not?
Where does the responsibility lie to ensure the right type is passed, with the function or with the caller?
I’m assuming with the caller, cos there ain’t much a function can do if null is automatically set to 0.

If you use null as a Number, like comparing it to a Number, it will evaluate to 0. What are you trying to accomplish, ultimately?

You have to remove “:Number= NaN”, and add reference to arguments of myFunc, because, if function recieves null it substitutes default value for the argument, it doesnt convert null to whatever the type of argument may be.
i.e.

function myFunc(i:*):void
{
 var ai:* = i;
 trace(ai);
 if (ai == null) trace ("argument #0 is null!");
 if (!isNaN(ai)) trace("May be a number!");
 if (isNaN(ai)) trace ("Not a number, but may be cast to number!");
 if (isNaN(ai/1)) trace ("Positively, not a number!");
 if (ai != NaN) trace ("ai != NaN");
}
function getUnknownValue():* {
 return null;
}
myFunc(0);
trace("-----------------");
myFunc(getUnknownValue());
myFunc('a');
trace("-----------------");

PS. null != NaN

But also NaN != NaN.


function meNaN(optionalParameter:Number = NaN):Boolean
{
    return isNaN(optionalParameter);
}

trace(meNaN());
trace(meNaN(1));
trace(meNaN(null));

This is an exmaple of what I’m getting at. The function has an optional parameter, and the functionality will depend on whether a number is passed or not.
If this function is being called from somewhere else in the program, and passed a variable that has been retrieved from somewhere else. As long as something is passed (whether an actual number or null) it will never be NaN.

So this means the parameter will have to be cast with a wildcard? Feels a bit hacky to me, but I get like this sometimes!

Anyway, I do understand the situation, just wondering how other people might have dealt with it before.

Ok, I got it. My problem was…

I had some functions with return types of Number. However, these functions would also return **null **if invalid data was passed, as is the case with many other classes and methods.

Or so I thought - because I was sure that back in AS2 **null **and **undefined **were considered the same. This definitely ain’t the case in AS3.

My understanding now is that **null **exists as an entity, but contains no data, whereas **undefined **doesn’t exist at all.

So my conclusion i fact if you want to either return ‘nothing’ from a function, return **undefined **- not null!

Thanks again for your input guys!

Why not? If you remove default argument’s value and try to divide anything that is not a number by 1 you’ll get NaN, try copypaste my example and run it…

Rather than return null, you could also look into working with try…catch…finally, and when a null value would be returned, instead throw an error you could then handle.

Oops, forgot I still had open threads. That project got quite intense. Thanks wvxvw for that example - there is a way of determining if a passed parameter is a number or not, which is good. I also have noticed that a lot of Flash classes use wildcard typing, so I suppose it’s not as evil as I first thought. And dthought, you’re right - throwing errors is something I haven’t done before, but it’s something I’m now starting to do. After all if your classes are written & documented properly then its up to whoever uses them to implement & handle them correctly.
Cheers!