2

I'd like to emulate ActiveRecord scopes on a CoffeeScript class.

What's tripping me up is the context when defining the @scope function. The @scope function itself should execute in the context of the underlying class, but the function it is passed should operate in the context of that instance.

Here is what I have, but the popped function ends up running in the context of Window instead of the instance that called it.

class Collection
  models: []

  @scope: (name, funct) ->
    @.prototype[name] = ->
      new @constructor(funct())

  constructor: (models) ->
    @models = models

class Bubbles extends Collection
  @scope 'popped', ->
    @models.slice(1, @models.length)

  first: ->
    @models[0]


console.log(new Bubbles([1,2,3,4]).popped()) # should return an instance of Bubbles with models == [2,3,4]

1 Answer 1

2

The problem is that you're calling funct as a simple function:

new @constructor(funct())

so @ inside funct is going to be window. You can use apply or call to specify what @ should be (i.e. to call the function as a method):

@scope: (name, funct) ->
  @::[name] = ->
    new @constructor(funct.apply(@))

Note that I've also switched to :: as that's more idiomatic CoffeeScript that prototype.

Demo: http://jsfiddle.net/ambiguous/9Pmcr/

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.