AS3: declaring an "undefined" parameter for int, uint or Number

Wikiup picture Wikiup · May 8, 2009 · Viewed 14.3k times · Source

I'd like to implement the following logic:

function setMyValue (myVar:int = undefined):void
{
    if (myVar == undefined)
    {
        /* Generate a value for myVar */
    }
    else
    {
        /* Use the supplied value for myVar */
    }
}

So if the value is supplied, use it. If not, generate it. Seems simple enough.

Problem is that AS3 doesn't like this. 'undefined' gets coerced into '0', so myVar is never undefined. I've tried variations with NaN, null, etc, but nothing has worked. The only kludge I can think of offhand is to supply some 'magic number' to use as default, but that's ugly. Anyone know a better solution?

Thanks!

Answer

dragonfly picture dragonfly · May 8, 2009

UPD (from my comment): It is certainly not a good practice to pick some magic number to indicate value absence, unless you can be completely sure this magic number would not appear as a result of some arithmetics (which generally is true). So the best approach here is either to use a wider type than int (e.g. Number), or pass some flag (Boolean value) to function, as well as int, to indicate actual value absence. Choice should depend on whether you want to emphasize the importance of fact that passed value is integral.


If you feel comfortable with expanding argument type, then you should use NaN and do this:

function setMyValue (myVar : Number = NaN) : void
{
    if ( isNaN(myVar) )
    {
        /* Generate a value for myVar */
    }
    else
    {
        /* Use the supplied value for myVar */
    }
}

That is both more technically accurate and it is also more stable. It will also allow you to strongly type at compile-time and would not cause weird bugs as in case of using Object.

Note that this will not work with int as one of the answers suggests. int has only numerical values, and NaN will get coerced to 0. You will need to use Number type.

If you're worried about performance - don't be. Using Number instead of int or uint is generally OK.


UPD: If you want to explicitly mark that argument should be integral just use additional flag and exact type - it would be much clearer.

function setMyValue (isIntValueSupplied : Boolean = false, intValue : int = 0) : void
{
    if ( isIntValueSupplied )
    {
        /* Generate or use a default value of intValue */
    }
    else
    {
        /* Use the supplied value for intValue */
    }
}

Another option is to define your own type with additional value, e.g. MaybeInt, which holds integer value and a flag (whether it was actually initialized or not). That way you would clearly signal that value should be integral or no-value. However, this approach may be a bit bulky.