加载中...

REPL


稳定度: 2 - 稳定

一个 读取-执行-打印-循环(REPL)可以用于单独的程序,也能很容易的被集成在其他程序中。REPL提供了一种交互着运行JavaScript然后查看结果的方式。它可以被用来调试,测试或只是尝试一些东西。

在命令行中不带任何参数直接执行iojs,你会进入REPL界面。它有一个极简的emacs行编辑器。

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

要使用高级的行编辑器的话,带着环境变量NODE_NO_READLINE=1启动io.js。它将会在允许你使用rlwrap的终端设置中,启动一个主要的调试REPL(main and debugger REPL)。

例如,你可以把以下内容加入bashrc文件:

  1. alias iojs="env NODE_NO_READLINE=1 rlwrap iojs"

内置的REPL(通过运行iojsiojs -i启动)可以被以下环境变量所控制:

  • NODE_REPL_HISTORY_FILE - 如果指定,那必须是一个用户可读也可写的文件路径。当给定了一个可用的路径,将启用持久化的历史记录支持:REPL历史记录将会跨iojs``REPL会话持久化。
  • NODE_REPL_HISTORY_SIZE - 默认为1000。与NODE_REPL_HISTORY_FILE结合,控制需要持久化的历史记录数量。必须为正数。
  • NODE_REPL_MODE - 可以是sloppystrictmagic中的一个。默认为magic,会自动在严格模式中执行"strict mode only"声明。

repl.start(options)

返回并启动一个REPLServer实例,继承于[Readline Interface][]。接受一个包含以下值得options对象:

  • prompt - 所有I/O的提示符。默认为>

  • input - 监听的可读流。默认为process.stdin

  • output - 输出数据的可写流。默认为process.stdout

  • terminal - 如果流需要被像TTY对待,并且有ANSI/VT100转义代码写入,设置其为true。默认为在实例化时检查到的output流的isTTY属性。

  • eval - 被用来执行每一行的函数。默认为被异步包装过的eval()。参阅下文的自定义eval的例子。

  • useColors - 一个表明了是否writer函数需要输出颜色的布尔值。如果设置了不同的writer函数,那么它什么都不会做。默认为REPL的终端值。

  • useGlobal - 若设置为true,那么REPL将使用全局对象,而不是运行每一个脚本在不同上下文中。默认为false

  • ignoreUndefined - 若设置为true,那么如果返回值是undefinedREPL将不会输出它。默认为false

  • writer - 当每一个命令被执行完毕时,都会调用这个函数,它返回了展示的格式(包括颜色)。默认为util.inspect

  • replMode - 控制是否REPL运行所有的模式在严格模式,默认模式,或混合模式("magic"模式)。接受以下值:

  • repl.REPL_MODE_SLOPPY - 在混杂模式下运行命令。
  • repl.REPL_MODE_STRICT - 在严格模式下运行命令。这与在每个命令前添加'use strict'语句相等。
  • repl.REPL_MODE_MAGIC - 试图在默认模式中运行命令,如果失败了,会重新尝试使用严格模式。

你可以使用你自己的eval函数,如果它包含以下签名:

  1. function eval(cmd, context, filename, callback) {
  2. callback(null, result);
  3. }

在用tab补全时 - eval将会带着一个作为输入字符串的.scope调用。它被期望返回一个scope名字数组,被用来自动补全。

多个REPL可以运行相同的io.js实例。共享同一个全局对象,但是各自的I/O独立。

下面是在stdin,Unix socket 和 TCP socket 上启动一个REPL的例子:

  1. var net = require("net"),
  2. repl = require("repl");
  3. connections = 0;
  4. repl.start({
  5. prompt: "io.js via stdin> ",
  6. input: process.stdin,
  7. output: process.stdout
  8. });
  9. net.createServer(function (socket) {
  10. connections += 1;
  11. repl.start({
  12. prompt: "io.js via Unix socket> ",
  13. input: socket,
  14. output: socket
  15. }).on('exit', function() {
  16. socket.end();
  17. })
  18. }).listen("/tmp/iojs-repl-sock");
  19. net.createServer(function (socket) {
  20. connections += 1;
  21. repl.start({
  22. prompt: "io.js via TCP socket> ",
  23. input: socket,
  24. output: socket
  25. }).on('exit', function() {
  26. socket.end();
  27. });
  28. }).listen(5001);

在命令行中运行这个程序会在stdin上启动一个REPL。另外的REPL客户端将会通过Unix socket或TCP socket连接。telnet在连接TCP socket时非常有用,socat在连接Unix socket和TCP socket时都非常有用。

通过从基于Unix socket 的服务器启动REPL,你可以不用重启,而连接到一个长久执行的(long-running)io.js进程。

一个通过net.Servernet.Socket实例运行“全特性”(终端)REPL的例子,参阅https://gist.github.com/2209310

一个通过curl(1)运行REPL的例子,参阅https://gist.github.com/2053342

Event: 'exit'

  • function () {}

当用户通过任意一种已定义的方式退出REPL时触发。具体地说,在REPL中键入.exit,两次按下Ctrl+C来发送SIGINT信号,按下Ctrl+D来发送结束信号。

例子:

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

Event: 'reset'

  • function (context) {}

REPL内容被重置时触发。当你键入.clear时发生。如果你以{ useGlobal: true }启动REPL,那么这个事件将永远不会触发。

例子:

  1. // Extend the initial repl context.
  2. r = repl.start({ options ... });
  3. someExtension.extend(r.context);
  4. // When a new context is created extend it as well.
  5. r.on('reset', function (context) {
  6. console.log('repl has a new context');
  7. someExtension.extend(context);
  8. });

REPL 特性

REPL内,按下Control+D将会退出。多行表达式可以被输入。Tab补全同时支持全局和本地变量。

核心模块将会被按需载入环境。例如,调用fs,将会从global.fs获取,作为require()``fs模块的替代。

特殊的变量_(下划线)包含了上一个表达式的结果。

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

REPL可以访问全局作用域里的任何变量。你可以通过将变量赋值给一个关联了所有REPLServercontext对象来暴露一个对象给REPL。例子:

  1. // repl_test.js
  2. var repl = require("repl"),
  3. msg = "message";
  4. repl.start("> ").context.m = msg;

context对象里的对象会表现得像REPL的本地变量:

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

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

  • .break - 当你输入一个多行表达式时,有时你走神了,或有时你不关心如何完成它了。.break将会让你重新来过。
  • .clear - 重置context对象为一个空对象并且清除所有多行表达式。
  • .exit - 关闭I/O流,意味着会导致REPL退出。
  • .help - 展示特殊命令列表。
  • .save 将当前的REPL会话保存入一个文件。

  • .save ./file/to/save.js

  • .load - 从一个文件中加载REPL会话。

  • .load ./file/to/load.js

这些组合键在REPL中有以下影响:

  • ctrl + C - 与.break关键字相似。终止当前命令。在一个空行上连按两次会强制退出。
  • ctrl + D - 与.exit关键字相似。
  • tab - 展示所有的全局和本地变量。

还没有评论.