jashkenas/coffeescript

`class B extends A` calls `A.extended(B)` when `A.extended` is a function

sstephenson opened this issue · 7 comments

It'd be useful if CoffeeScript could invoke a callback on a class after it's subclassed with the extends keyword.

With such a callback, you could implement a base class that propagates its class methods to subclasses:

class Base
  @extended: (subclass) ->
    for key, value of @
      subclass[key]: value

class Element extends Base
  @fromHTML: (html) ->
    node: # ...
    new @(node)

class MyElement extends Element
  # ...

MyElement.fromHTML("<div>...</div>")

You could also implement a test case class that collects its subclasses and runs them automatically:

class TestCase
  @subclasses: []
  @extended: (subclass) ->
    subclass.extended: TestCase.extended
    TestCase.subclasses.push subclass

class BaseTest extends TestCase
  # ...

class ElementTest extends TestCase
  # ...

for testCase in TestCase.subclasses
  TestRunner.run testCase

Mind pasting an example of the JavaScript you'd like to generate for this? Something along these lines?

if (Base.extended) Base.extended(Element);

Or do you think there needs to be a check to ensure that it's a function?

For what it's worth, I am strongly in favor of this callback. It would be similar to Ruby's Class::inherited method (http://ruby-doc.org/core/classes/Class.html#M002785), and provide a very useful metaprogramming capability that is not otherwise possible to implement.

+1 to this. In general, I'd like to see CoffeeScript classes become more powerful constructs. And the test case example is awesome.

Here's my proposal. We'd only call extended if it's a function. And we'd move the __superClass__ assignment after the call to extended, so class method propagation can be implemented without having to skip over the __superClass__ property.

sstephenson's patch is now merged to master. Closing the ticket.

very cool!

I've just been pointed to this ticket from: #1762 ...what do you guy's think this?