Skip to content

Class system extendability - A simple solution #1762

Closed
@ghost

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions