
Description
Hi,
The one thing keeping me from using CoffeeScript full-time is that it's class system cannot be extended in any way. Below is an idea that allows users to hook into the class system, it's very similar to that in Ruby and Spine.js.
I am suggesting that the following coffee script:
class Bar
class Foo extends Bar
myInstanceMethod: -> console.log 'I am an instance method';
@myClassMethod: -> console.log 'I am a class method';
Should generate:
var Bar, Foo;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
var mixin = function(target, obj) {
for (var key in obj) { if (__hasProp.call(obj, key)) target[key] = obj[key]; } };
mixin(child, parent);
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
child.include = child.include || function(obj) { mixin(this.prototype, obj); };
child.extend = child.extend || function(obj) { mixin(this, obj); };
if (parent.inherited) parent.inherited(child);
return child;
};
Bar = (function() {
function Bar() {}
return Bar;
})();
Foo = (function() {
__extends(Foo, Bar);
function Foo() {
Foo.__super__.constructor.apply(this, arguments);
}
Foo.include({
myInstanceMethod: function() {
return console.log('I am an instance method');
}
});
Foo.extend({
myClassMethod: function() {
return console.log('I am a class method');
}
});
return Foo;
})();
This way, should Bar want to hook into the class system it could do the following:
class Bar
@include: (obj) ->
console.log "About to declare: '#{key}' on proto" for key in obj
super
@extend: (obj) ->
console.log "About to declare: '#{key}' on class" for key in obj
super
class Foo extends Bar
myInstanceMethod: -> console.log 'I am an instance method';
@myClassMethod: -> console.log 'I am a class method';
I think this would make CoffeeScript's class system truly powerful and allow things like Ext's preprocessors... the applications are endless. The other benefit of this is that the resulting minified JS would be smaller due to the object notation used in include
and extend
. Obviously the include
and extend
function names are just a suggestion but I think the likeness to Ruby is a good thing. To avoid conflicts with existing code, they could always be __include
and __exclude
.
This tiny change also introduces Ruby-esque 'Modules' e.g.
CommonInstanceMethods =
sharedFunction -> console.log 'I come from CommonInstanceMethods'
CommonClassMethods =
sharedFunction -> console.log 'I come from CommonClassMethods'
class Foo
@include CommonInstanceMethods
@extend CommonClassMethods
class Bar
@include CommonInstanceMethods
@extend CommonClassMethods
I would create a patch but don't know enough about parsers to be able to implement it. I really hope we can add this as currently there is no way to extend the class system.
Thanks,
Jamie