Sunday, May 2, 2010

Event driven application and the most basic Listener module

Event driven programming is a common technique particularly common in JavaScript applications.

When


The most classic application is the one with DOM and assigned listeners.
We have basically no idea about "what happens when" and we delegate asynchronous logic to our listeners, waiting for user actions.
This kind of approach could be implemented in whatever application creating a chain of events or notifications that must occur when something expected happens.
Other examples of event driven programming are sockets, Ajax calls, and any sort of notification that may occur in order to let the surrounding logic act accordingly.
Often combined with registry pattern, event driven programming can be found inside UI frameworks where components, as example, are notified when sub-components are added or removed. In this way the component always knows its status and it can change accordingly (redraw, repaint, properties, accessors, counters, other notifications).

What

Following the DOM example or, back in 2004, the ActionScript model, events are nothing more than callbacks associated via unique identifier: the event name. The natural order for these callback is FIFO and usually each callback is "fired" with the same object/event as single argument. One de-facto standard about events is that usually there is no need to add twice the same so that one event will be fired just once.
Since the order matter, there is no way to prevent events already assigned to do not fire. The same is for DOM events, preventDefault or stopPropagation won't stop other events associated with the same node to do not fire but, if used, the chain or the behavior after these events are fired may be different.

How

This is one of the most basic Listener implementation: it's a module, suitable for mixins, is a Singleton, usable and shareable across the whole application, and finally it's a little piece of code, basically unbreakable and reliable for what it does.
This is a basic usage example for the Listener module:

function MyListener() {
// create the "protected" listener hash
this.initListener();
}
MyListener.prototype = Listener;

var ml = new MyListener();

var test = function (arg) {
alert(ml === this && arg === 2); // true
};

ml.addListener("test", test);
// won't add the same event
ml.addListener("test", test);

// fire the event
ml.fireListener("test", 2);

// remove the listener
ml.removeListener("test", test);

// check precedent operation
alert(ml.hasListener("test", test)); // false

// fire a listener in any case
ml.fireListener("test", 2); // nothing happens


Why

With this basic functionality we can already start to create an event driven application firing events whenever it is necessary.
As example, an object with a remove/destroy method may involve soe notification. All we need to do in this case is to use something such:

this.fireEvent("destroy", this);

before or after destroy operations. In this way whatever other part of the application that added a listener may act accordingly and the chain of notifications can establish a new environment, if necessary.
The behavior is the same we can found in native DOM events listeners. If a listener is removed runtime it won't be fired and same is if a listener will be added runtime, it will be executed only next time unless we are not firing it again (which means all others will be fired again).

This post would like to be just a starting point for this kind of approach, sometimes we may need to deal with objects that don't know what could happen if one of them has been removed, added, created, or changed so in this way we have a basic component to deal with. Have fun ;-)

Wednesday, April 28, 2010

Object.defineProperty - A Missed Opportunity

Just a quick post about some clever hack we should probably forget ... make old scripts less obtrusive using new ES5 features.
I am talking bout those guys out there that use scripts with a classic:

onload = function () { ... };
// or
this.onload = ...
// or
window.onload ...
// or
self.onload ...
// etc etc


Apparently WebKit Nightly fires an error when we try to define getters and setters via Object.defineProperty and this is already enough to remove that "hoooraayyyy" for my silly test .... here the code:

Object.defineProperty(this, "onload", (function (self, callback) {
function onload(e) {
while (callback.length) {
callback.shift().call(self, e);
}
}
self.addEventListener ?
self.addEventListener("load", onload, false) :
self.attachEvent("onload", onload)
;
return {
get: function () {
return onload;
},
set: function (onload) {
callback.push(onload);
}
};
}(this, [])));


If we put above snippet before any other script, we can be almost sure that nobody will be able to break anything with classic obtrusive operations:

// test above concept via Chrome and maybe IE8 or others
onload = function () {
alert(1);
};

this.onload = function () {
alert(2);
};


That's it, something that may have been good will probably be just a proof of concept :-)

Sunday, April 25, 2010

JSON __sleep, __wakeup, serialize and unserialize

The JSON protocol is a de facto standard used in many different environments to transport objects, included arrays and Dates plus primitives such: strings, numbers, and booleans ... so far, so good!
Since this protocol is widely adopted but it has not the power that a well known function as is the PHP serialize one has, we are often forced to remember how data has been stored, what does this data represent, and eventually convert data back if we are dealing with instances rather than native hashes.
If we consider the ExtJS library architecture, we can basically have a snapshot of whatever component simply storing its configuration object. The type will eventually tell us how to retrieve a copy of the original component back and without effort at all.
Since JSON is the preferred protocol to store data in WebStorages, databases, files, etc etc, and since we can save basically only hashes, loosing every other property, I have decided to try this experiment able to bring some magic in the protocol itself.

JSONSerialize

The absolutely alpha version of this experiment has been stored here, in my little repository. If more than one developer, e.g. me, is interested, I may consider to put it in google code or github with a better documentation while what I can do right now, is to show you what JSONSerialize can do for us, step after step.

Normal JSON.stringify Behavior

This is what happens if we use JSON.stringify, or JSON.serialize, when an object is simply .... well, an object.

// let's test in console or web
if (typeof alert === "undefined") alert = print;

// our "class"
function A() {}

// our instance
var a = new A;

// a couple of dynamic properties
a.a = 123;
a.b = 456;

// our JSON call
var json = JSON.serialize(a);
alert(json); // {"a":123,"b":456}

Nothing new, serialize acts exactly as JSON.stringify, with or without extra arguments ... but things become a bit more interesting now ...

The _sleep Method

In the PHP world we all know there are several methods able to bring some magic in our classes and __sleep is one of these methods. Since the double underscore is usually considered a bad practice, due to private core magic functionalities (e.g. __noSuchMethod__, __defineGetter/Setter__, others) I have decided to call it simply _sleep, considering it a sort of magic protected method, whatever it means in JavaScript :-)

A.prototype._sleep = function () {
return ["a"];
};

json = JSON.serialize(a);
alert(json); // {"a":123}

The aim of _sleep is to return an array with zero, one, or more public properties we would like to export. As we can see, JSON.serialize will take care of this operation returning only what is present in the list.
In few words, no needs to send properties we don't need, cool?
Another advantage of a sleep method is to notify, close, disconnect, or do whatever other operation we need to mark the instance as serialized. In other words sleep could be useful every time we need to deal with a variable that may be updated elsewhere using JSON as transport protocol (postMessage, others).

The serializer Property

_sleep is already a good start point but, if we don't know anything else about that hash, how can we understand which kind of instance was the a variable?

alert(JSON.unserialize(json).constructor);
// Object

Too bad, we have been able to define what we would like to export, but no way to understand what we actually exported.
This is where the serializer property becomes handy, letting JSON.serialze behaves differently.

// define the serializer
A.prototype.serializer = "A";

// re-assign the string and check it out
json = JSON.serialize(a);

alert(json); // {"a":123,"_wakeup":"A"}

// what's new? just this:

alert(JSON.unserialize(json).constructor);
// the function A() {} ... oooh yeah!!!

In few words, with or without a _sleep method, we can bring back to their initial status serialized objects ... but why that _wakeup property? Thank's for asking!

The _wakeup Method

As is for PHP, there is a __wakeup method too which is invoked as soon as the string is unserialized! Being this method somehow protected, I thought it was the best one to put into the JSONSerialize logic.

// let's define a _wakeup method
A.prototype._wakeup = function () {
alert(this instanceof A);
// will be true !!!
};

// let's try again
a = JSON.unserialize(json);

// ... oooh yeah!

As the PHP page shows in some example, the _wakeup function can become really useful when we are saving a database connection or a WebStorage wrapper or whatever cannot be persistent and requires to be initialized so .... at least we can save some info rather than ask them every time, isn't it?
The moment _wakeup will be invoked the instance will already have every exported property assigned, exactly as is for PHP ... wanna something more?

serialize And unserialize Methods

The PHP Serializable interface brings some other magic via the SPL: we decide what we want to export and we receive it back when unserialize is invoked. Same is for JSONSerialize, with higher priority over _sleep and _wakeup but not better performances (right now, I may consider to avoid some extra operation to follow current PHP status tho ...)

// introduce the serialize method
A.prototype.serialize = function () {
return JSON.stringify({c:789});
};

// try this at home
json = JSON.serialize(a);
alert(json); // {"c":789,"_wakeup":"A"}

// this will call the _wakeup since
// unserialize has not been defined yet
// please note the a property won't be there anymore
// cause serialize returned a c instead
a = JSON.unserialize(json);

// let's have priority via unserialize
A.prototype.unserialize = function (data) {
this.b = JSON.parse(data).c;
};

// let's try again, _wakeup won't be invoked
a = JSON.unserialize(json);

// a won't be there, but b will
alert([a.a, a.b]); // undefined,789

And that's all folks!

JSONSerialize Pros

The serializer property accepts namespaces and does not use evaluation. The whole little script does not use evaluation at all and I think this is good, specially for security reason.
Nested objects and arrays are supported as well which means that we can serialize complex hierarchies and have them back without effort and already initialized.

JSONSerialize Cons

Nested means loops, as is for the JavaScript JSON implementation performances are surely slower than a native implementation. At the same time we should consider when we need it, cause our own implementation to bring instances back could cost more. Finally, if we all like this, we may push some browser vendor for a core implementation, no?
Another performance problem is with serialize and unserialize since these requires double parsing in order to respect the behavior.

As Summary

It's not the first time I am trying to enhance the JSON protocol to fit my requirements and this is probably the less obtrusive and secure way I could came out with. I hope somebody will appreciate at least the idea and I am up for all your thoughts ;-)