namespaces in coffeescript

2019-02-14 19:17发布

I'd like to use namespaces as one would in javascript by using the keyword "with", but CoffeeScript reports this as a reserved keyword and refuses to compile is there any way I could use namespaces in cs?

In particular, I want to include a CoffeeScript file dynamically (trusted source), like loading models for a database schema, but I want the included script to have access to a local namespace.


Edit:

Here's what I want to do. I am setting up a web framework that maps the directory tree to an application based on express and mongoose. For example, there's a sub-directory 'models' that contains a file 'user.coffee' with code like this inside:

name:
    type: String
    unique: on
profiles: [ Profile ]

Whereby Profile is a class that sits in a local object named model. When the user model is being loaded, I wanted it to access the model classes that sit in my local model store.

My work-around for now was to write model.Profile into the file 'user.coffee'. Hope it is clear what I mean.


2nd Edit

Here's how I did it without using with:

user.coffee

name:
    type: String
    unique: on
profiles: [ @profile ]

profile.coffee

content: String

And here's how it's dynamically loaded:

for fm in fs.readdirSync "#{base}/models"
    m = path.basename fm, '.coffee'
    schema[m] = (()->
        new Schema coffee.eval (
            fs.readFileSync "#{base}/models/#{fm}", 'utf8'
        ), bare: on
    ).call model
    mongoose.model m, schema[m]
    model[m] = mongoose.model m

Seems an okay solution to me.

4条回答
来,给爷笑一个
2楼-- · 2019-02-14 19:42

Having someone else's opinion forced on you? It's Hack Time™!

o =
  a: 1
  b: 2
  c: 3

`with(o) {//`
  alert a
`}`

"Compiles" to:

var o;
o = {
  a: 1,
  b: 2,
  c: 3
};
with(o) {//;
alert(a);
};

It's a pity that this is another area where Doug Crockford's opinion is taken as gospel. with Statement Considered Harmful rejects it on the basis of ambiguity of property writes, but ignores its usefulness when used with a read-only context object, such as a context object which defines a DSL-like API.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-02-14 19:42

Just found that on the CoffeeScript FAQ page about "Variable Importing":

https://github.com/jashkenas/coffee-script/wiki/FAQ

It seems, that the use of this technique is discouraged in CoffeeScript and not supported.

查看更多
不美不萌又怎样
4楼-- · 2019-02-14 19:43

No. However, you can use destructuring assignment to achieve a similar effect.

{foo, bar, baz} = require 'toocoollib'
foo 'whoa!'

You should also be aware that the with keyword is deprecated and is a syntax error in ES5 strict mode. The consensus among mainstream JS hackers is that with is a bad idea.

If you posted an example of what you would like to do, I could give a more specific answer.

查看更多
手持菜刀,她持情操
5楼-- · 2019-02-14 19:47

The Coco fork of CoffeeScript supports a with syntax; see https://github.com/satyr/coco/wiki/additions. However, that syntax simply sets the value of this to the target object in a block, rather than compiling to the problematic and deprecated with keyword.

Let's say that you wanted to emulate Coco's with syntax in CoffeeScript. You'd do something like this:

withObj = (obj, func) -> func.call obj

Then you could write

withObj = (obj, func) -> func.call obj
withObj annoyingly.lengthy.obj.reference, ->
  @foo = 'bar'
  @bar = 'baz'

Of course, in such simple cases, it's better to use a utility function like jQuery or Underscore's extend:

_.extend annoyingly.lengthy.obj.reference, foo: 'bar', bar: 'baz'
查看更多
登录 后发表回答