2012-06-11 27 views
11

Tôi vừa mới bắt đầu sử dụng Coffeescript và bảng điều khiển Coffeescript và Dấu gạch dưới. Tuy nhiên, bất cứ khi nào tôi định nghĩa một hàm, Coffeescript quyết định rằng _ có nghĩa là hàm đó, và dường như quên nhiệm vụ ban đầu của _ = require 'underscore'.Dấu gạch dưới không hoạt động trong giao diện điều khiển của Coffeescript

Tại sao điều này lại xảy ra? Làm thế nào tôi có thể ngăn chặn nó?
(Tôi thực sự muốn có thể sao chép mã dán từ các tệp của mình vào bảng điều khiển.)

(Có _ có ý nghĩa đặc biệt trong bảng điều khiển Coffeescript không? Có nghĩa là "kết quả cuối cùng" hay gì đó? Điều đó muốn giải thích vấn đề của tôi)

Chi tiết:

$ 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 

Trả lời

20

Các CoffeeScript REPL có this JavaScript tại trái tim của nó:

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); 
} 

Vì vậy, nếu lệnh cuối cùng trả về một cái gì đó thì _ sẽ là cái gì đó. Tôi không thể tìm thấy bất kỳ tài liệu nào về điều này mặc dù nhưng tìm kiếm _ không phải là một hoạt động hiệu quả khủng khiếp. Nếu bạn muốn sử dụng Underscore.js trong CoffeeScript REPL, bạn sẽ phải gọi nó là cái gì đó khác hơn là _.

Nhờ Trevor Burnham (người đã viết the book vì vậy tôi nghĩ chúng ta có thể tin tưởng anh ấy về vấn đề này), chúng tôi biết rằng CoffeeScript REPL sử dụng _ như là kết quả cuối cùng để phù hợp với hành vi của các node.js REPL:

REPL Tính năng
[...]
Biến đặc biệt _ (gạch dưới) chứa kết quả của biểu thức cuối cùng.

Ruby's irb cũng làm như vậy.

+3

Câu trả lời đúng, ngắn: '_' thực sự có nghĩa là" kết quả cuối cùng ". Đây không phải là tài liệu rất tốt, nhưng nó được thực hiện cho sự nhất quán với REPL 'node'. Than ôi, điều này có nghĩa là bạn sẽ phải lập bản đồ Gạch dưới với một số số nhận dạng khác. –

+2

Tôi nghĩ rằng cách thực hành tốt nhất là sử dụng '__' (hai dấu gạch dưới) cho dấu gạch dưới trong CoffeeScript REPL:' __ = require 'underscore'' – robbrit

+3

Điều này khá bực bội khi sao chép/dán mã hiện tại vào REPL. Điều tốt nhất tôi đã tìm thấy là thiết lập '__ = require 'underscore" ', và sau đó gõ' __ 'trong REPL trước bất kỳ mã nào bạn muốn thực hiện. ('__ ' sẽ trả về dấu gạch dưới, vì vậy '_' sẽ trỏ đến thư viện gạch dưới cho lệnh tiếp theo chạy.) –

Các vấn đề liên quan