James Forbes
James Forbes

Reputation: 1497

Assign @ to a separate object for ease of namespacing

In coffeescript you can assign an object or class to the global namespace by prepending the definition with the @ symbol.

e.g.

class @Dog #This is now available via window.Dog due to the @
   constructor : () ->

But is there someway to assign the @ symbol to another object, instead of window?

When I tried @ = {}, I got error: unexpected =

This would allow you to always define your objects to be a namespace, but change your mind about what namespace that is at a later time. It allows you to avoid exporting on a case by case basis. You can set @ to global while testing and then set it to an alternate namespace when deployed.

If there is a better approach, or an alternate way to achieve a similar goal that would be great too!

Upvotes: 0

Views: 43

Answers (3)

topr
topr

Reputation: 4612

Using @ as reference to window object may be misleading and can lead to errors (when context changes). Better is to declare some custom namespace.

You put a line in the first script you're loading:

window.myns ?= {}

...and later use it instead of @ like:

class myns.Dog

Just to be safe you add the namespace declaration line on top of each file in which you'll be reffering to it. It's not mandatory though. Just be sure scripts are loaded in proper order.

Upvotes: 0

epidemian
epidemian

Reputation: 19219

You cannot change the this at the top level, but you can call a function with a different this scope:

(->
  class @Dog
    talk: -> console.log 'woof!'
  class @Cat
    talk: -> console.log 'meow'
).call animals = {}

# Now the animals "namespace" has a Cat and a Dog properties.
(new scope.Cat).talk()

The example doesn't make too much sense, as it could be written as animals = {}; class animals.Cat and avoid the need for that extra nesting level, but if you're looking for changing the this dynamically at some point, it's nice to know about the existence of Function#call :)

Upvotes: 0

Naftali
Naftali

Reputation: 146310

You cannot assign something to this, this is the scope variable.

I guess you could make some function to set the namespace:

@scope = do ( -> return @ ) #change `@` at the end to your namespace

Then you would do:

class @scope.Dog
   constructor: () ->
      ...

Which parses to:

this.scope = (function() {
  return this;
})();

this.scope.Dog = (function() {

  function Dog() {
      ...
  }

  return Dog;

})();

Upvotes: 1

Related Questions