14

I found this snippet on the Coffeescript FAQ for creating simplistic namespaces ..

# Code:
#
namespace = (target, name, block) ->
  [target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3
  top    = target
  target = target[item] or= {} for item in name.split '.'
  block target, top

# Usage:
#
namespace 'Hello.World', (exports) ->
  # `exports` is where you attach namespace members
  exports.hi = -> console.log 'Hi World!'

namespace 'Say.Hello', (exports, top) ->
  # `top` is a reference to the main namespace
  exports.fn = -> top.Hello.World.hi()

Say.Hello.fn()  # prints 'Hi World!'

That is all well and good, but I am having a great deal of trouble doing this with the class keyword. Such that ..

namespace 'Project.Something', (exports) ->
   exports.something = -> class something
    // .. code here
   exports.somethingElse = class somethingElse extends something

can anyone shed some light on the syntax that would accomplish this?

3 Answers 3

24

Even better, the class syntax allows for the name to actually be in the form of a member, so you can actually just do:

namespace 'Secrets', (exports) ->
  class exports.Hello
    constructor: ->
      @message = "Secret Hello!"

a = new Secrets.Hello
console.log a.message

Full fiddle here: http://jsfiddle.net/7Efgd/1/

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

1 Comment

This is a valid solution as well. It's really a matter of preference. I find the example above a little easier for me to understand.
19

The trick is to create the class first

class MyFirstClass
  myFunc: () ->
    console.log 'works'

class MySecondClass
  constructor: (@options = {}) ->
  myFunc: () ->
    console.log 'works too'
    console.log @options

Then somewhere near the end of the file export all the classes than need to be exposed.

namespace "Project.Something", (exports) ->
  exports.MyFirstClass = MyFirstClass
  exports.MySecondClass = MySecondClass

Later on you can use the classes as so:

var firstClass = new Project.Something.MyFirstClass()
firstClass.myFunc()

var secondClass = new Project.Something.MySecondClass 
  someVar: 'Hello World!'

secondClass.myFunc()

4 Comments

There we go! It was so simple, but so frustrating at the same time. Thank you!
There should be a method that does this for you :(
Doesn't this defeat the purpose of Namespacing? Seen as MyFirstClass is now defined both in the Namespace and outside of it? @ChrisSubagio's answer seems like a more correct way to do it.
No. Coffeescript wraps that file within an anonymous function so MyFirstClass is not leaked to the global namespace. It's only exposed to the global namesapce through the namespace function.
1

How about using something like this?

module =
    Hello: class Hello extends Backbone.Model
        constructor: ->
            @message = 'Hello'

    Hello2: class Hello2 extends Backbone.View
        constructor: ->
            @message = 'Hello2'

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.