Tim Stephens
Tim Stephens

Reputation: 117

Coffeescript Inheritance: Static variables/methods

In other OOP languages, the following is a common form of abstraction

class AbstractClass
  myVar: null

  @doSomething: ->
    console.log myVar

class Child extends AbstractClass
  myVar: 'I am a child'

Calling Child.doSomething() should print "I am a child". I should also be able to pass Child.doSomething as a callback and have it print the same. I have tried all combinations of with or w/o @, using semicolons and equals to define myVar, I can't figure it out. What is the proper way to do this in CoffeeScript?

edit

I think I oversimplified my example, because I can't get it to work (further edit: now working with this solution). Here is the real code (with the suggested solution in place):

class AbstractController
  @Model: null

  @index: (req, res) ->
    console.log @
    console.log @Model
    @Model.all?(req.params)

class OrganizationController extends AbstractController
  @Model: require "../../classes/community/Organization"

In my routing file

(express, controller) ->
  router = express.Router({mergeParams: true})
  throw new Error("Model not defined") unless controller.Model?
  console.log controller
  router
  .get "/:#{single}", _.bind(controller.show, controller)
  .get "/", _.bind(controller.index, controller)
  .post "/", _.bind(controller.post, controller)

Passing OrganizationController to this function correctly logs the OrganizationController object, so I know it's getting there:

{ [Function: OrganizationController]
  Model: { [Function: Organization] ...},
  index: [Function],
  __super__: {} }

But when I hit that route, the two console.log calls print out

{ [Function: AbstractController]
  Model: null,
  index: [Function] }
null

And I get an error: "Cannot read property 'all' of null"

Upvotes: 1

Views: 287

Answers (1)

JLRishe
JLRishe

Reputation: 101662

You were missing a few @s. The following prints I am a child:

class AbstractClass
  @myVar: null

  @doSomething: ->
    console.log @myVar

class Child extends AbstractClass
  @myVar: 'I am a child'

Child.doSomething()

But if you want to pass it as a callback function, you need to bind it to Child:

callf = (f) ->
  f()

callf Child.doSomething                # prints undefined
callf Child.doSomething.bind(Child)    # prints I am a child

Upvotes: 4

Related Questions