I implemented something like this for my last project, but I think you can make JS class creation far more ruby-like (and flexible, for that matter), by not passing an explicit hash to your class creation function, but instead building the class in a callback:
// code start
var Event = Class.define(function()
{
this.speak = function()
{
console.log("HI");
}
// since you can just write code in here
// metaprogramming is easy:
["attack", "defend"].each(function(name) {
this[name] = function() {console.log(name);}
}.bind(this));
// or build reusable metaprogramming facilities
// and use them here
this.$setters(["x", "y", "z"]);
this.$memoize("expensiveFunc", function() {
// blah
});
this.$inherited = function(derivedClass) { ... }
});
Basically, the class define method would create a special 'class-creation' object, and would invoke the user provided function with the class creation object as the this pointer. After the callback finished, I would use the class-creation object to build the actual class.
Being actual able to write code inside your class definition is a much more flexible way to define your objects - and it's also how Ruby does it.
I was making the opposite assertion. How are classes simpler than prototypes? If you want to add behavior to the proto and the clone, you just add a method to the proto. If you want to add behavior to a class and its instances, you have to do a fair bit more.
Prototypes offer no contract, so it's up to the consumer to ensure that the object received is acceptable. Classes offer a contract, so if an object is an instance, it's guaranteed to work (Liskov, etc.).
Basically, the idea of OOP is information hiding and polymorphism, and prototype-based objects throw both of these concepts away. The result is more complicated code in general.
Ruby Classes don't provide a contract either. You can add and remove methods to your heart's desire.
information hiding is the principle of segregation of design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed
How are prototypes inferior to classes with respect to information hiding? They provide the ability to easily change the implementation while maintaining the interface.
How do prototypes inhibit polymorphism? All of the prototype languages that I know of (Javascript, Io, Self, Lua ...) make it easy to take advantage of polymorphism.
Less context switching when you're developing web applications that require a significant amount of Javascript code. Less context switching means you get to stay in flow and get more done.
You can do prototype-style inheritance in ruby, but no one does it. In fact, most new languages that come out express no interest in this style. It makes me wonder why the Javascript people are so convinced that why they have is that good.
I don't know - I love PHP classes but I'd love to see PHP with prototype-style inheritance (if PHP had classes for strings, etc. in respect to basic variable types). I think the "everything is an object" route is great and coupling that with prototypes exemplifies that decision's greatness.
However, I really do think that JavaScript needs all of the great things ECMA 5 displays first and foremost (such as strict mode, getters/setters/enumerable/configurable/writable for property descriptors).
18 comments
[ 2.7 ms ] story [ 45.4 ms ] threadBasically, the class define method would create a special 'class-creation' object, and would invoke the user provided function with the class creation object as the this pointer. After the callback finished, I would use the class-creation object to build the actual class.
Being actual able to write code inside your class definition is a much more flexible way to define your objects - and it's also how Ruby does it.
Basically, the idea of OOP is information hiding and polymorphism, and prototype-based objects throw both of these concepts away. The result is more complicated code in general.
information hiding is the principle of segregation of design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed
http://en.wikipedia.org/wiki/Information_hiding
How are prototypes inferior to classes with respect to information hiding? They provide the ability to easily change the implementation while maintaining the interface.
How do prototypes inhibit polymorphism? All of the prototype languages that I know of (Javascript, Io, Self, Lua ...) make it easy to take advantage of polymorphism.
Ruby Hashes and Enumerators have way more functionality than the stock js types.
Is it worth the 40k minimized for the full include? That I dunno.
Brings to mind the expression "A bug-for-bug port of the existing system."
However, I really do think that JavaScript needs all of the great things ECMA 5 displays first and foremost (such as strict mode, getters/setters/enumerable/configurable/writable for property descriptors).
John Resig does an excellent job of summing up ECMA 5 pragmatically (it truly must be great to work on JavaScript stuff as a day job): http://ejohn.org/blog/ecmascript-5-objects-and-properties/
http://code.google.com/p/joose-js/