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