The random utterances of David Arno

AS3Initializers: a simple AS3 object initialization framework

As a result of two separate lines of thought: currying and simplifying the initialisation of objects, I have come up with a framework that offers curried initialisers for AS3.

A while ago, Grant Skinner wrote a piece regarding adding object initializers to AS3. He proposed a syntax that would enable the coder to instantiate an object and set properties on it all in one statement like this:

var o:SomeClass = new SomeClass(1, 2, 3) {x:[], y:"lala", z:false};

The equivalent in the current AS3 syntax would be:

var o:SomeClass = new SomeClass(1, 2, 3);
o.x = [];
o.y = "lalala";
o.z = false;

The former form, whilst arguably no more than syntactic sugar, is – to my mind at least – quicker to write, easier to read and less error prone. However beyond voting for it on Adobe’s bug & issue management system, I didn’t give it much thought at the time.

Also recently, I have been investigating partial functions and currying and had been trying to come up with a real-world use case for curried functions in ActionScript. A chance conversation with a colleague resulted in the idea of curried constructors. Imagine that SomeClass above had the following constructor signature:

function SomeClass(machineID:int, timeout:int, userID:int)

Imagine an application running on a single machine (ie the machine ID won’t change) where the timeout is defined in a config file, read at the start up (so it won’t change either). If I need to instantiate a number of SomeClass objects (eg the user keeps changing), I could implement some sort of Provider or Dependency Injection pattern to make the unchanging values available throughout the system. A really nice alternative though would be to be able to do something like:

var partial:SomeClass.curried = new SomeClass(machineID, timout);

Then when a user logs in, the code need just be:

var user:SomeClass = new partial(userID);

Thinking back to Grant’s idea of an initializer, I combined the two ideas and decided what I really wanted was curried initializers, which would support something like:

var partial:SomeClass.curried = new SomeClass(1, 2) {x:[], y:"la"};
var o:SomeClass = new partial(3) {z:false};

This achieves the same result as the very first example at the top of this article, but allows the process to be curried.

Clearly this sort of functionality isn’t going to appear in AS3 any time soon (if ever). So I wrote a framework that achieves the same effect in AS3 as it is now. As Grant noted in his article, the framework cannot do compile-time checking, not is the syntax quite as neat as the above examples, but I think it’s pretty good despite those limitations.

By way of demonstrating it, take the following class which extends Sprite:

package
{
  import flash.display.Sprite;
 
  public class Circle extends Sprite
  {
    ...
    public function Circle(radius:Number, colour:uint)
    {
      ...
    }
 
    public function set angle(value:Number):void
    {
      calcSpeeds(value, null);
    }
 
    public function set speed(value:Number):void
    {
      calcSpeeds(null, value);
    }
 
    protected function calcSpeeds(spd:*, ang:*):void
    {
      ...
    }
  }
}

By using the AS3Initializer framework, I can initialise many instances of Circle, all positioned at a fixed point, but with other varying attributes thus:

var initializer:CurriedInitializer =
  new CurriedInitializer(Circle, {r:5, x:225, y:225}, ["r", "c"]);
 
for (var i:int = 0; i < 100; i++)
{
  var colour:uint = ...;
  var angle:Number = ...;
  var speed:Number = ...;
 
  var sprite:Circle = 
     initialiser.createNew({c:colour, 
                            angle:angle, 
                            speed:speed}) as Circle;
  addChild(sprite);
}

The constructor for CurriedInitializer takes three parameters: the class it is to handle, a set of values to be applied to all instances of the class and an array defining the class’ constructor parameter names. Calling createNew on the CurriedInitializer instance generates a new instance of the required class (in our case Circle) and initialises it with a combination of the default attributes and the those supplied with the createNew call.

This code (fully fleshed out) gives rise to the following demo. Click on the white rectangle below to make it start (and keep clicking to add 100 more balls at a time to it):

This movie requires Flash Player 9

The framework is very lightweight and consists of just three classes: CurriedInitializer, Initializer (a simpler version that doesn’t support currying) and InitializerError (which is thrown by the previous two classes when a class is initialized incorrectly).

If this framework proves popular, I’ll stick it up on github or the like and will look at trying to optimise it (it is likely to be relatively slow at the moment). In the meantime, you can download the AS3Initializer SWF, plus its source and that of the above demo here.

The online documentation for AS3Initializers can be accessed here.


Share This Post...
No comments yet, click here to be the first

No comments yet. Be the first.

Leave a reply

Close