鍍金池/ 教程/ HTML/ REPL
punycode
Zlib
V8
Debugger
Readline
DNS
File System
util
Query String
Assert
執(zhí)行<code>JavaScript</code>
Console
Errors
Events
Timers
HTTP
Child Process
Buffer
Stream
Path
Modules
net
REPL
process
Global Objects
Crypto
StringDecoder
TTY
TLS (SSL)
OS
HTTPS
UDP / Datagram Sockets
Cluster
URL

REPL

穩(wěn)定度: 2 - 穩(wěn)定

一個 讀取-執(zhí)行-打印-循環(huán)(REPL)可以用于單獨(dú)的程序,也能很容易的被集成在其他程序中。REPL提供了一種交互著運(yùn)行JavaScript然后查看結(jié)果的方式。它可以被用來調(diào)試,測試或只是嘗試一些東西。

在命令行中不帶任何參數(shù)直接執(zhí)行iojs,你會進(jìn)入 REPL 界面。它有一個極簡的 emacs 行編輯器。

mjr:~$ iojs
Type '.help' for options.
> a = [ 1, 2, 3];
[ 1, 2, 3 ]
> a.forEach(function (v) {
...   console.log(v);
...   });
1
2
3

要使用高級的行編輯器的話,帶著環(huán)境變量NODE_NO_READLINE=1啟動io.js。它將會在允許你使用rlwrap的終端設(shè)置中,啟動一個主要的調(diào)試REPL(main and debugger REPL)。

例如,你可以把以下內(nèi)容加入bashrc文件:

alias iojs="env NODE_NO_READLINE=1 rlwrap iojs"

內(nèi)置的REPL(通過運(yùn)行iojsiojs -i啟動)可以被以下環(huán)境變量所控制:

  • NODE_REPL_HISTORY_FILE - 如果指定,那必須是一個用戶可讀也可寫的文件路徑。當(dāng)給定了一個可用的路徑,將啟用持久化的歷史記錄支持:REPL歷史記錄將會跨iojs``REPL會話持久化。
  • NODE_REPL_HISTORY_SIZE - 默認(rèn)為1000。與NODE_REPL_HISTORY_FILE結(jié)合,控制需要持久化的歷史記錄數(shù)量。必須為正數(shù)。
  • NODE_REPL_MODE - 可以是sloppy,strictmagic中的一個。默認(rèn)為magic,會自動在嚴(yán)格模式中執(zhí)行"strict mode only"聲明。

repl.start(options)

返回并啟動一個REPLServer實(shí)例,繼承于[Readline Interface][]。接受一個包含以下值得options對象:

  • prompt - 所有I/O的提示符。默認(rèn)為>。

  • input - 監(jiān)聽的可讀流。默認(rèn)為process.stdin。

  • output - 輸出數(shù)據(jù)的可寫流。默認(rèn)為process.stdout。

  • terminal - 如果流需要被像 TTY 對待,并且有ANSI/VT100轉(zhuǎn)義代碼寫入,設(shè)置其為true。默認(rèn)為在實(shí)例化時檢查到的output流的isTTY屬性。

  • eval - 被用來執(zhí)行每一行的函數(shù)。默認(rèn)為被異步包裝過的eval()。參閱下文的自定義eval的例子。

  • useColors - 一個表明了是否writer函數(shù)需要輸出顏色的布爾值。如果設(shè)置了不同的writer函數(shù),那么它什么都不會做。默認(rèn)為REPL的終端值。

  • useGlobal - 若設(shè)置為true,那么REPL將使用全局對象,而不是運(yùn)行每一個腳本在不同上下文中。默認(rèn)為false。

  • ignoreUndefined - 若設(shè)置為true,那么如果返回值是undefined,REPL將不會輸出它。默認(rèn)為false

  • writer - 當(dāng)每一個命令被執(zhí)行完畢時,都會調(diào)用這個函數(shù),它返回了展示的格式(包括顏色)。默認(rèn)為util.inspect。

  • replMode - 控制是否REPL運(yùn)行所有的模式在嚴(yán)格模式,默認(rèn)模式,或混合模式("magic"模式)。接受以下值:

    • repl.REPL_MODE_SLOPPY - 在混雜模式下運(yùn)行命令。
    • repl.REPL_MODE_STRICT - 在嚴(yán)格模式下運(yùn)行命令。這與在每個命令前添加'use strict'語句相等。
    • repl.REPL_MODE_MAGIC - 試圖在默認(rèn)模式中運(yùn)行命令,如果失敗了,會重新嘗試使用嚴(yán)格模式。

你可以使用你自己的eval函數(shù),如果它包含以下簽名:

function eval(cmd, context, filename, callback) {
  callback(null, result);
}

在用 tab 補(bǔ)全時 - eval將會帶著一個作為輸入字符串的.scope調(diào)用。它被期望返回一個scope名字?jǐn)?shù)組,被用來自動補(bǔ)全。

多個REPL可以運(yùn)行相同的io.js實(shí)例。共享同一個全局對象,但是各自的 I/O 獨(dú)立。

下面是在stdin,Unix socket 和 TCP socket 上啟動一個REPL的例子:

var net = require("net"),
    repl = require("repl");

connections = 0;

repl.start({
  prompt: "io.js via stdin> ",
  input: process.stdin,
  output: process.stdout
});

net.createServer(function (socket) {
  connections += 1;
  repl.start({
    prompt: "io.js via Unix socket> ",
    input: socket,
    output: socket
  }).on('exit', function() {
    socket.end();
  })
}).listen("/tmp/iojs-repl-sock");

net.createServer(function (socket) {
  connections += 1;
  repl.start({
    prompt: "io.js via TCP socket> ",
    input: socket,
    output: socket
  }).on('exit', function() {
    socket.end();
  });
}).listen(5001);

在命令行中運(yùn)行這個程序會在stdin上啟動一個REPL。另外的REPL客戶端將會通過 Unix socket或 TCP socket連接。telnet在連接 TCP socket時非常有用,socat在連接 Unix socket和 TCP socket時都非常有用。

通過從基于 Unix socket 的服務(wù)器啟動REPL,你可以不用重啟,而連接到一個長久執(zhí)行的(long-running)io.js進(jìn)程。

一個通過net.Servernet.Socket實(shí)例運(yùn)行“全特性”(終端)REPL的例子,參閱https://gist.github.com/2209310。

一個通過curl(1)運(yùn)行REPL的例子,參閱https://gist.github.com/2053342。

Event: 'exit'

  • function () {}

當(dāng)用戶通過任意一種已定義的方式退出REPL時觸發(fā)。具體地說,在REPL中鍵入.exit,兩次按下Ctrl+C來發(fā)送SIGINT信號,按下Ctrl+D來發(fā)送結(jié)束信號。

例子:

r.on('exit', function () {
  console.log('Got "exit" event from repl!');
  process.exit();
});

Event: 'reset'

  • function (context) {}

當(dāng)REPL內(nèi)容被重置時觸發(fā)。當(dāng)你鍵入.clear時發(fā)生。如果你以{ useGlobal: true }啟動REPL,那么這個事件將永遠(yuǎn)不會觸發(fā)。

例子:

// Extend the initial repl context.
r = repl.start({ options ... });
someExtension.extend(r.context);

// When a new context is created extend it as well.
r.on('reset', function (context) {
  console.log('repl has a new context');
  someExtension.extend(context);
});

REPL 特性

REPL內(nèi),按下Control+D將會退出。多行表達(dá)式可以被輸入。Tab 補(bǔ)全同時支持全局和本地變量。

核心模塊將會被按需載入環(huán)境。例如,調(diào)用fs,將會從global.fs獲取,作為require()``fs模塊的替代。

特殊的變量_(下劃線)包含了上一個表達(dá)式的結(jié)果。

> [ "a", "b", "c" ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
4

REPL可以訪問全局作用域里的任何變量。你可以通過將變量賦值給一個關(guān)聯(lián)了所有REPLServercontext對象來暴露一個對象給REPL。例子:

// repl_test.js
var repl = require("repl"),
    msg = "message";

repl.start("> ").context.m = msg;

context對象里的對象會表現(xiàn)得像REPL的本地變量:

mjr:~$ iojs repl_test.js
> m
'message'

以下是一些特殊的REPL命令:

  • .break - 當(dāng)你輸入一個多行表達(dá)式時,有時你走神了,或有時你不關(guān)心如何完成它了。.break將會讓你重新來過。
  • .clear - 重置context對象為一個空對象并且清除所有多行表達(dá)式。
  • .exit - 關(guān)閉 I/O 流,意味著會導(dǎo)致REPL退出。
  • .help - 展示特殊命令列表。
  • .save 將當(dāng)前的REPL會話保存入一個文件。

    • .save ./file/to/save.js
  • .load - 從一個文件中加載REPL會話。
    • .load ./file/to/load.js

這些組合鍵在REPL中有以下影響:

  • ctrl + C - 與.break關(guān)鍵字相似。終止當(dāng)前命令。在一個空行上連按兩次會強(qiáng)制退出。
  • ctrl + D - 與.exit關(guān)鍵字相似。
  • tab - 展示所有的全局和本地變量。
上一篇:Errors下一篇:Child Process