Thursday, September 6, 2007

Enumerable Class for Flash

DOWNLOAD:
http://www.youbits.com/jumpship/JSEnumerable.as

Anybody who has spent any time with Ruby have surely come to appreciate the simple elegance of blocks especially as it relates to enumerable objects like arrays. For those not familiar, you can write something like:

myArray.each {|item|
item.do.something
}

This will iterate over the contents of the array and pass each item to a code block {...} allowing you to perform an operation. In Ruby, variables ( in this case items in the array ) are available within the block by defining them inside the "|...|".

The Ruby syntax makes it elegant but the true worth is in the concept. How many countless hours would be saved over the course of a Flash programmers career if he/she didn't have to always write out "for (var i = 0; i < myArray.length: i++) ...". Well we can't change the language but maybe we can attempt to use some Ruby concepts to make our lives easier.

The ajax library Prototype uses an Enumerable module in JavaScript to Incorporate the Ruby concepts of blocks and the Ruby Enumerable Module to do some pretty powerful things. After taking a look at their work, I thought it would be worthwhile to try to implement an enumerable (JSEnumerable) class in ActionScript that lets you traverse and search any list-based data type that extends it.

The Syntax looks something like:

myEnum.each(function(item) {
item.do.something();
});

You can also add a second parameter to the block function with will contain the index of the item. That would look like:

myEnum.each(function(item, index) {
item.do.something();
trace(index) // 0,1,2,3,...
});

Using the JSEnumerable class requires extending it and defining a hook function called doEach. Since not all enumerable objects are arrays, this class defines how to traverse the data. So if a class extended the JSEnumerable class and had all of its data stored in a private Array called myData, doEach might look something like:

protected override function doEach(iterator:Function) {
for (var i = 0; i < myData.length; i++) {
iterator(myData[i]);
}
}

if myData were an Object, the doEach function might look like:

protected override function doEach(iterator:Function) {
for (var a in myData) {
iterator(myData[a]);
}
}

The JSEnumerable class also includes the following methods:

public function all(iterator:Function):Boolean
true if all items match the conditions in the block, false otherwise.

public function any(iterator:Function):Boolean
true if any items match the conditions in the block, false otherwise.

public function collect(iterator:Function):Array
iterates over the items and returns a new array according to the code in the block.

public function detect(iterator:Function):Boolean
returns the item if the block conditions are true, false otherwise.

public function findAll(iterator:Function):Array
returns an array of all items that match the block conditions

public function grep(pattern:RegExp, iterator:Function):Array
returns the item if the pattern matches the string representation of the item. the item must have a toString() method to produce a result.

public function inc(object):Boolean
true if the object matches an item, false otherwise.

public function max(iterator:Function):*
returns the maximum value as determined by the block

public function min(iterator:Function):*
returns the minimum value as determined by the block

public function reject(iterator:Function):Array
returns an array of all items that DON'T match the block conditions

As far as JumpShip goes, future versions of the JSDataModel and JSDataRecord will extend this class and all the above functions will be available.

Sunday, September 2, 2007

JumpShip for AS3 Released!!!
After an exhaustive port. the AS3 version of JumpShip has been released! The principals differ little from the original AS2 version of JumpShip so there should be very few migration issues (hopefully).

While undergoing the migration I have had a few epiphanies about how to better implement the JumpShip Framework for AS3 / Flex / AIR and the coming months will be devoted to exploring those possibilities. Honestly, most of the room for improvement is on the Ruby on Rails end of the Rails gateway to put in more in line with the REST movement happening over there.

So there are a lot of things on my plate but help from anybody who may be interested is always welcome.

Jamie Scanlon



JumpShip for AS2 Released.
JumpShip, the original AS2 version, has been updated with a major release. It includes several bug fixes to the Ruby on Rails gateway, and a glaring implementation error in the JSDataModel. There are also bug fixes in the JSLayoutManager Class in the extras package.

Since we are all moving rapidly to AS3 I cannot promise that the AS2 version will be updated for much longer. Brave AS2 diehards are welcome to pick up this project where I leave off.