I'm working through Trevor Burnham's CoffeeScript book and I've run into a weird puzzle concerning this
/@
. The puzzle has a few parts (and I may be just very confused), so I'll try to make this as clear as I can.
The main problem I'm having is that I get varied and inconsistent results running the same code through different REPLs and interpreters. I'm testing with (1) the coffee
REPL and interpreter, (2) Node's REPL and interpreter and (3) v8's REPL and interpreter.
Here's the code, first as Coffeescript then as Javascript:
// coffeescript
setName = (name) -> @name = name
setName 'Lulu'
console.log name
console.log @name
// Javascript via the coffee compiler
(function() {
var setName;
setName = function(name) {
return this.name = name;
};
setName('Lulu');
// console.log for node below - print for v8
// uncomment one or the other depending on what you're trying
// console.log(name);
// console.log(this.name);
// print(name);
// print(this.name);
}).call(this);
Here are the results:
$ coffee setName.coffee
Lulu
undefined
# coffee REPL
# This appears to be a bug in the REPL
# See https://github.com/jashkenas/coffee-script/issues/1444
coffee> setName = (name) -> @name = name
[Function]
coffee> setName 'Lulu'
'Lulu'
coffee> console.log name
ReferenceError: name is not defined
at repl:2:1
at Object.eval (/Users/telemachus/local/node-v0.4.8/lib/node_modules/coffee-script/lib/coffee-script.js:89:15)
at Interface.<anonymous> (/Users/telemachus/local/node-v0.4.8/lib/node_modules/coffee-script/lib/repl.js:39:28)
at Interface.emit (events.js:64:17)
at Interface._onLine (readline.js:153:10)
at Interface._line (readline.js:408:8)
at Interface._ttyWrite (readline.js:585:14)
at ReadStream.<anonymous> (readline.js:73:12)
at ReadStream.emit (events.js:81:20)
at ReadStream._emitKey (tty_posix.js:307:10)
coffee> console.log @name
undefined
$ v8 setName.js
Lulu
Lulu
# v8 REPL
>> (function(){var setName; setName=function(name){return this.name=name;};setName('Lulu');print(name);print(this.name);}).call(this);
Lulu
Lulu
# Switch print to console.log or require puts from sys
$ node setName.js
Lulu
undefined
# node REPL
> (function() {
... var setName;
... setName = function(name) {
... return this.name = name;
... };
... setName('Lulu');
... console.log(name);
... console.log(this.name);
... }).call(this);
Lulu
Lulu
So the real questions, I suppose, are (1) what results should I expect and (2) why can't these interpreters and REPLs get along? (My going theory is that v8 is right: in the global context name
and this.name
should be the same thing, I would have thought. But I'm very ready to believe that I don't understand this
in Javascript.)
Edit: If I add this.name = null
/@name = null
before calling setName
(as Pointy suggests below) then Coffeescript and Node give me 'Lulu' and 'null' back but v8 still returns 'Lulu' for both. (v8 still makes more sense to me here. I set name
to null
initially in the global context, but then setName
sets it (in the global context) to 'Lulu'. So afterwards, this is what I should see there.)