2012-06-11 5 views
11

Ich habe gerade angefangen, Coffeescript und die Coffeescript-Konsole und Underscore zu verwenden. Wenn ich jedoch eine Funktion definiere, entscheidet Coffeescript, dass _ diese Funktion bedeutet und die ursprüngliche Zuweisung von _ = require 'underscore' zu vergessen scheint.Underscore funktioniert nicht in der Konsole von Coffeescript

Warum passiert das? Wie kann ich das verhindern?
(ich würde wirklich in der Lage sein mag Einfügen von Code aus meinen Dateien in die Konsole zu kopieren.)

(Hat _ hat eine besondere Bedeutung in der Coffee Konsole? Ist es „das letzte Ergebnis“ oder etwas bedeuten? Das wäre meine Frage erläutern)

Details:?

$ coffee 
coffee> _.contains [1, 2, 3], 3 # no Underscore, initially 
TypeError: Cannot call method 'contains' of undefined 
    at ... 
coffee> 
coffee> _ = require 'underscore' 
{ [Function] 
    _: [Circular], 
    VERSION: '1.3.3', 
    forEach: [Function], 
    ... 

coffee> _.contains [1, 2, 3], 3 # now Underscore works fine 
true 
coffee> 
------> someFunction = (a, b) -> # define a function ... 
......> a + b 

[Function] 
coffee> 
coffee> _.contains [1, 2, 3], 3  # now `_` is not Underscore any more! 
TypeError: Object function (a, b) { # Does `_` mean "last result" or sth? 
    return a + b; 
} has no method 'contains' 
    at evalmachine.<anonymous>:3:7 
    at Object.eval (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/coffee-script.js:142:17) 
    at Interface.<anonymous> (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/repl.js:131:40) 
    at Interface.emit (events.js:67:17) 
    at Interface._onLine (readline.js:162:10) 
    at Interface._line (readline.js:426:8) 
    at Interface._ttyWrite (readline.js:603:14) 
    at ReadStream.<anonymous> (readline.js:82:12) 
    at ReadStream.emit (events.js:88:20) 
    at ReadStream._emitKey (tty.js:327:10) 
coffee> 
coffee> _ = require 'underscore' 
coffee> _.contains [1, 2, 3], 3 # Now all is fine again, for a short while 
true 

Antwort

20

Der Coffee REPL hat this JavaScript an seinem Herzen:

try { 
    _ = global._; 
    returnValue = CoffeeScript["eval"]("_=(" + code + "\n)", { 
    filename: 'repl', 
    modulename: 'repl' 
    }); 
    if (returnValue === void 0) { 
    global._ = _; 
    } 
    repl.output.write("" + (inspect(returnValue, false, 2, enableColours)) + "\n"); 
} catch (err) { 
    error(err); 
} 

Also, wenn der letzte Befehl etwas zurückgegeben hat, dann _ wird das etwas sein. Ich kann keine Dokumentation darüber finden, aber die Suche nach _ ist keine sehr produktive Aktivität. Wenn Sie Underscore.js in CoffeeScript REPL verwenden möchten, müssen Sie es als etwas anderes als _ nennen.

Dank Trevor Burnham (die the book schrieb, so denke ich, dass wir ihn auf diese vertrauen können) wissen wir, dass der Coffee REPL _ als das letzte Ergebnis verwendet, das Verhalten der node.js REPL entsprechen:

REPL Eigenschaften
[...]
Die Sondervariable _ (Unterstrich) enthält das Ergebnis des letzten Ausdrucks.

Rubys irb macht das gleiche.

+3

Richtige, kurze Antwort: '_' bedeutet tatsächlich "letztes Ergebnis". Dies ist nicht sehr gut dokumentiert, aber es wurde aus Gründen der Konsistenz mit der 'node' REPL gemacht. Leider bedeutet dies, dass Sie Underscore einem anderen Bezeichner zuordnen müssen. –

+2

Ich denke, die beste Praxis war die Verwendung von "__" (zwei Unterstriche) für Underscore in der CoffeeScript REPL: '__ = erfordern 'Unterstrich' ' – robbrit

+3

Dies ist ziemlich frustrierend beim Kopieren/Einfügen von bestehenden Code auf die REPL. Das Beste, was ich gefunden habe, ist das Setzen von '__ = require" Unterstrich "' und dann die Eingabe von '__ ' in der REPL vor dem Code, den Sie ausführen möchten. ('__ ' gibt einen Unterstrich zurück, so dass '_' auf die Unterstrich-Bibliothek für den nächsten Befehl zeigt, der ausgeführt wird.) –

Verwandte Themen