Przemek
Przemek

Reputation: 6700

Using util.inherits() "breaks" prototyping when using CoffeeScript

I encountered a problem after switching from server-side JavaScript to CoffeeScript in a Node.js application. Let's consider the following code:

# require our tools
util = require "util"
events = require "events"

# define an object class and a method using CoffeeScript syntax
class TestObject
  method: () -> #1
    console.log "Test"

# set up inheritance using Node.js util module
util.inherits TestObject, events.EventEmitter #2

# make an instance of object
instance = new TestObject()

# and boom! it crashes ;(
instance.method()

The above code will crash because of the error: TypeError: Object #<TestObject> has no method 'method'

The error is caused by setting up the inheritance at #2. The above code compiles to following JavaScript (deleted some newlines for the sake of readability):

(function() {
  var TestObject, events, instance, util;

  util = require("util");
  events = require("events");

  TestObject = (function() {
    function TestObject() {}

    TestObject.prototype.method = function() {
      return console.log("Test");
    };

    return TestObject;
  })();

  util.inherits(TestObject, events.EventEmitter);

  instance = new TestObject();
  instance.method();

}).call(this);

You can see that the util.inherits() method is called after adding the method to prototype. So, the method would be lost after switching prototypes.

Is there an elegant way to set up the inheritance without breaking the awesome CoffeeScript class notation?

Upvotes: 1

Views: 1056

Answers (2)

offner
offner

Reputation: 659

You can also use the CoffeeScript syntax for inheritance, "extends":

util = require "util"
events = require "events"

class TestObject extends events.EventEmitter
  method: () -> #1
    console.log "Test"

instance = new TestObject()
instance.method()

Upvotes: 4

Raynos
Raynos

Reputation: 169401

class TestObject extends events.EventEmitter
  method: () -> #1
    console.log "Test"

Is there an elegant way to set up the inheritance without breaking the awesome CoffeeScript class notation?

You can just not use coffeescript and use objects

var extend = /* implement extend [snip] */

var TestObject = extend({}, events.EventEmitter.prototype, {
    method: function () {
        console.log("test")
    }
})

As an aside, unless you really like the CoffeeScript syntax you should stick to JavaScript. Especially for libraries, people who write open source libraries in CoffeeScript deserve to be shot.

Upvotes: 2

Related Questions