I've been experimenting with extending Class.create() to do object casting as well as its usual object creation. The idea is to use syntax similar to performing object casts in C++. For example:

int i = (int)3.141;
Tree t = (Tree)obj;

Casting can also be used to do type verification, which Javascript is loose about.

Tree t = (Tree)human;  //throws exception
Tree t = (Tree)pine;  //success

I thought about extending the function returned by Class.create() that performs different actions depending on whether it is called as a function or as a constructor.

car = new MyCar();
car = MyCar(obj);  //may succeed or throw an error
MyCar(obj).startEngine();

Then I thought, if the cast method was customizable, then implementators can use it to convert one completely different object into another under the guise of a cast. e.g.,

TabbedPane($("tab_elm").firstChild).activateTab();

The main difference between:

TabbedPane($("tab_elm"));

and

new TabbedPane($("tab_elm"));

is that the latter semantically represents creating a new tabbed pane object, while the former represents getting the tabbed pane object from an existing source (possibly a hashtable) when it is provided with a DOM reference.

My dual purpose Class.create() implementation is as follows:

var Class = {
 create: function() {
   return function() {
     if(this instanceof arguments.callee) {
       this.initialize.apply(this, arguments);
     } else {
       if(arguments.callee.cast) {
         return arguments.callee.cast.apply(this, arguments);
       } else {
         return null;
       }
     }
   }
 }
};

If the implementor decides to support casting, they would then implement their own cast method:

var MyCar = Class.create();
MyCar.cast = function(obj) {
 return (MyCar.prototype.isPrototypeOf(obj)) ? obj : null;
};

You may have noticed that I return a null instead of throwing an exception in the code above. The purpose is to aid in debugging. Under some circumstances, exceptions do not keep their line numbers when thrown, but if a user tries to dereference a null, the exception does keep the line number. So if the user calls MyCar(human).startEngine(), the dereferencing will throw an exception and return the line number at the point where it is dereferenced, which happens to be the point of the type cast.

What are your thoughts?


_______________________________________________
Rails-spinoffs mailing list
Rails-spinoffs@lists.rubyonrails.org
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs

Reply via email to