Search code examples
javascriptcoffeescriptprototypejsrickshaw

CoffeeScript: Extend super method like in Rickshaw Prototype example


I'm playing with the fantastic Rickshaw library which uses Prototype's class-based OOP system. This includes the extend method which allows a sub-class to extend a method in a parent class like this:

Parent class:

defaults: function() {
  return {
    tension: 0.8,
    // etc...
  };
}

Sub class:

defaults: function($super) {
  return Rickshaw.extend( $super(), {
    fill: true,
    // etc...
  } );
}

I'm trying to find the syntax to do the same in CoffeeScript, so that CoffeeScript handles the Class inheritance rather than Prototype. Can you help?

EDIT

Thanks to @tomahaug's answer I got this working, and I have now realised there is a better way. While $super is a Prototype feature, extend is actually defined both in Prototype and the Rickshaw top-level object, like this:

extend: (destination, source) ->
  for property of source
    if (source.hasOwnProperty(property))
      destination[property] = source[property]
  destination

So making use of this method, the solution looks like this:

defaults: () ->
  Rickshaw.extend super(), 
    fill: true,
    // etc...

So the only way this could be improved another step is if it turns out that this is built into CoffeeScript in some way.


Solution

  • If you want to call the parent method and then decorate the result with more information before it's returned, you can do it like this with pure CoffeeScript:

    class Parent
      defaults: () ->
        return {
           tension: 0.8
        }
    
    class Sub extends Parent
      defaults: () ->
        r = super
        r.fill = true
    
        return r
    
    sub = new Sub 
    
    sub.tension # 0.8
    sub.fill # true
    

    Using a library like http://underscorejs.org/ would probably make it a little prettier as you could do:

      defaults: () ->
        _.extend super, {
          fill: true
        }