namespaces in coffeescript
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.
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.
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'
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.
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.
精彩评论