views:

2862

answers:

9

Actionscript 3.0 (and I assume Javascript and ECMAScript in general) lacks pass-by-reference for native types like ints. As a result I'm finding getting values back from a function really clunky. What's the normal pattern to work around this?

For example, is there a clean way to implement swap( intA, intB ) in Actionscript?

A: 

If ActionScript works like Javascript,

[a,b] = [b,a]
Nick Retallack
Sorry, but that doesn't work in ActionScript
Turambar
+4  A: 

I Believe the best you can do is pass a container object as an argument to a function and change the values of some properties in that object:

function swapAB(aValuesContainer:Object):void
{
    if (!(aValuesContainer.hasOwnProperty("a") && aValuesContainer.hasOwnProperty("b")))
        throw new ArgumentError("aValuesContainer must have properties a and b");

    var tempValue:int = aValuesContainer["a"];
    aValuesContainer["a"] = aValuesContainer["b"];
    aValuesContainer["b"] = tempValue;
}
var ints:Object = {a:13, b:25};
swapAB(ints);
hasseg
A: 

hasseg, I'm holding out hope somebody knows a trick that's more elegant, but it seems likely that your answer is the best one.

I guess the natural follow up is: Does this limitation drive anyone else crazy, or is it just me? :)

Matt W
+4  A: 

I suppose an alternative would be somewhere defining this sort of thing ...

public class Reference {
    public var value:*;
}

Then use functions that take some number of Reference arguments to act as "pointers" if you're really just looking for "out" parameters and either initialize them on the way in or not and your swap would become:

function swap(Reference a, Reference b) {
    var tmp:* = a.value;
    a.value = b.value;
    b.value = tmp;
}

And you could always go nuts and define specific IntReference, StringReference, etc.

imaginaryboy
+2  A: 

You could also use a wrapper instead of int:

public class Integer
{
    public var value:int;

    public function Integer(value:int)
    {
     this.value = value;
    }
}

Of course, this would be more useful if you could use operator overloading...

Turambar
A: 

This is nitpicking, but int, String, Number and the others are passed by reference, it's just that they are immutable. Of course, the effect is the same as if they were passed by value.

Theo
+1  A: 

It is annoying. But if you use different idioms than in e.g. C#, you can get reasonable-quality results. If you need to pass a lot of parameters back and forth, pass in an object filled with the needed data, and change the object's parameters when you return. The Object class is for just this sort of thing.

If you just need to return a bunch of data, return an Object. This is more in keeping with the ECMAScript style than pass-by-ref semantics.

A: 

Destructuring assignment (e.g. [a,b] = [b,a]) isn't defined in the ECMA-262 3 specification, and it's not implemented in JavaScript 1.5, which is the version equivalent to the JScript implementation in IE. I've seen this syntax in the AS4 specifications preview though, and I believe it's part of JavaScript 1.7.

actionscribe
A: 

Just look at some Java code. Java has had the convention that reference types are passed by reference and primitive types are passed by value since it's inception. It's a very good model in many ways.

But talking about swap, the best and easiest way to do a swap in Java/AS3 is with the following three lines:

var temp:int = array[i];
array[j] = array[i];
array[i] = temp;

Theres not really any reason to use a function to do a simple swap, when you can do it faster with just 3 lines.

acgeek