Reputation: 3029
foo.coffee:
class Foo
constructor: ->
console.log BAR
module.exports = Foo
main.coffee:
BAR = 1
class Bar
constructor: ->
console.log BAR
new Bar()
Foo = require './foo'
new Foo()
then
$ coffee main.coffee
1
ReferenceError: BAR is not defined
Why BAR
isn't accessible inside the instance of Foo
?
Can I make it 'visible' to Foo
objects (besides of explicitly passing it to a constructor)?
Upvotes: 2
Views: 446
Reputation: 78599
I think the problem is that in CoffeeScript when you declare a variable it is always compiled to a local variable.
Therefore, in your declaration above, when you do BAR=1
that gets compiled to var BAR=1
. So, the variable is always scoped locally and it means it is not accessible to other modules.
So, the solution that Jed Schneider gave you is the correct one, with just one caveat, in Node.js, when you are in a module, the this
reference points to the module.exports
object and not to the global
object as Jed seemed to suggest (this is a source of confusion between node.js and the browser, since in the browser it does behave as Jed explained).
So, this is always true
//module.js
console.log(this==module.exports) //yield true
Whereas within a function, the this
keyword would point to the global object. So, this is also true:
//module.js
(function(){
console.log(this==global); //yields true
})()
Being this the case, to solve your problem, you can use Jed Schneider approach, but make sure to wrap your code inside an IIFE so that your this
points to global
and not to module.exports
.
So, this produces your expected results:
do ->
@BAR = 1
class Bar
constructor: ->
console.log BAR
new Bar()
Foo = require './foo'
new Foo()
This produces the output
1
1
Upvotes: 2
Reputation: 14671
class Bar
constructor: ->
console.log @BAR
and then setting
@BAR = 1
should do what you expect. this is shorthand for this.
which will place it on the global object, as you would expect constants to be defined. personally, I'd make a constants namespace and export that, the same as you do Foo
.
Upvotes: 0