OK, my guess would be that everybody used a function at one point or another. But there are some things which are less than obvious about an actionscript function. Let’s take a quick look.
Calling functions
Let’s create a simple function which will accept any number of parameters.
{
var val:int = 0;
for each (var i:int in arg)
val+=i;
return val;
}
// The usual way to call it
sum(0,1,2);
But that’s something everybody knew how to do. The interesting thing is that in Actionscript 3.0 there is a class called Function which also has it’s own methods defined, and all the functions are instances of that class. Most of the methods are inherited from Object but there are two defined for it, which are used to achieve a similar thing – calling the function, this are apply() and call(). The first parameter of both functions is almost always ignored [1].
The definition of call – call(thisArg:*, ...args):* shows that it also takes any number of parameters, than it uses them as arguments, so, as the first parameter is ignored – sum.call(null,0,1,2) is the same as sum(0,1,2).
The problem with calling functions like this is that you actually need to know how many parameters you’re going to use.
Luckily apply() has an array as a second parameter. Which means you can call a function, and pass any number of parameters as an Array. Quick sample of achieving the exact same functionality as before using apply.
var params:Array = [0,1,2];
sum.apply(null,params);
Which is much more flexible.
arguments variable
One more thing which is worth knowing is that inside functions you can access the arguments variable. It’s holds all the variables passed to the function, with the limitation that it doesn’t work when using the ...arg notation in the function definition. So this will not work:
function sum(...arg):int
{
trace (arguments);
// throws an error
[...]
}
But it will work with functions without the ...arg in the definition, for example this prints out both strings:
{
trace (arguments);
}
Apart from that this variable also holds the reference to the currently executing function in the arguments.callee property. Things like this come in handy sometimes.
Sample
Using all the tools described (callee, arguments, apply) we can build a quick sample, a class that records the calls to it’s functions in an easy way, and is able to replay them when needed.
CallRecorder.as
{
import mx.collections.ArrayCollection;
public class CallRecorder
{
// Just a sample function
public function printJohn(s:String):void
{
rememberTheCall(arguments);
trace ('John says ' + s);
}
// Just a another sample function
// notice that it has a different set of arguments
public function printBob(s:String,times:int = 1):void
{
rememberTheCall(arguments);
while (times-- > 0)
trace ('Bob says ' + s);
}
/** Replays all the calls in memory **/
public function replay():void
{
replayIsOn = true;
trace ("--- Starting the replay ---");
// Notice we actually don't need to worry
// about the arguments
for each (var arg:Object in memory)
(arg.callee).apply(this,arg);
replayIsOn = false;
trace ("--- Stoping the replay ---");
}
/** True if currently replaying **/
private var replayIsOn:Boolean = false;
/** Used for storing the history of function calls **/
private var memory:ArrayCollection = new ArrayCollection();
/** Stores a call in memory, if not called while replay **/
private function rememberTheCall(passedArguments:Object):void
{
if (!replayIsOn)
memory.addItem(passedArguments);
}
}
}
Sample execution:
recorder.printBob("I do");
recorder.printJohn("I do too");
recorder.printBob(":)",3);
recorder.printJohn(":)");
recorder.replay();
// results in
// Bob says I do
// John says I do too
// Bob says :)
// Bob says :)
// Bob says :)
// John says :)
// --- Starting the replay ---
// Bob says I do
// John says I do too
// Bob says :)
// Bob says :)
// Bob says :)
// John says :)
// --- Stoping the replay ---
Not a great piece of software but hopefully interesting.
———————————–
[1] The only case it’s not ignored which I could find is when using anonymous functions.
LiveDocs on Function class
LiveDocs on arguments class
by Russ
20 Feb 2010 at 20:16
That is interesting, I always wondered what …args meant in a function definition, now I know, thanks!