Update how REPLServer uses contexts

* Always use `this.context` or `self.context`.
* Move `resetContext` to `REPLServer.createContext`.
* Add `REPLServer.resetContext`, memoize `context` here.
* Memoize `exports.repl` in `start`.

Closes GH-851.
This commit is contained in:
Ben Weaver 2011-03-29 14:08:39 -04:00 committed by Ryan Dahl
parent bfa9db9dd6
commit d63a551f86

View File

@ -60,27 +60,14 @@ module.filename = process.cwd() + '/repl';
// hack for repl require to work properly with node_modules folders
module.paths = require('module')._nodeModulePaths(module.filename);
function resetContext() {
context = vm.createContext();
for (var i in global) context[i] = global[i];
context.module = module;
context.require = require;
context.global = context;
context.global.global = context;
for (var i in require.cache) delete require.cache[i];
}
// Can overridden with custom print functions, such as `probe` or `eyes.js`
exports.writer = util.inspect;
function REPLServer(prompt, stream) {
var self = this;
if (!context) resetContext();
if (!exports.repl) exports.repl = this;
self.context = context;
self.resetContext();
self.bufferedCommand = '';
if (stream) {
@ -159,7 +146,7 @@ function REPLServer(prompt, stream) {
// First we attempt to eval as expression with parens.
// This catches '{a : 1}' properly.
ret = vm.runInContext('(' + self.bufferedCommand + ')',
context,
self.context,
'repl');
if (typeof ret !== 'function') success = true;
} catch (e) {
@ -168,11 +155,11 @@ function REPLServer(prompt, stream) {
if (!success) {
// Now as statement without parens.
ret = vm.runInContext(self.bufferedCommand, context, 'repl');
ret = vm.runInContext(self.bufferedCommand, self.context, 'repl');
}
if (ret !== undefined) {
context._ = ret;
self.context._ = ret;
self.outputStream.write(exports.writer(ret) + '\n');
}
@ -215,10 +202,33 @@ exports.REPLServer = REPLServer;
// prompt is a string to print on each line for the prompt,
// source is a stream to use for I/O, defaulting to stdin/stdout.
exports.start = function(prompt, source) {
return new REPLServer(prompt, source);
var repl = new REPLServer(prompt, source);
if (!exports.repl) exports.repl = repl;
return repl;
};
REPLServer.prototype.createContext = function() {
var context = vm.createContext();
for (var i in global) context[i] = global[i];
context.module = module;
context.require = require;
context.global = context;
context.global.global = context;
return context;
};
REPLServer.prototype.resetContext = function(force) {
if (!context || force) {
context = this.createContext();
for (var i in require.cache) delete require.cache[i];
}
this.context = context;
};
REPLServer.prototype.displayPrompt = function() {
this.rli.setPrompt(this.bufferedCommand.length ? '... ' : this.prompt);
this.rli.prompt();
@ -503,7 +513,7 @@ function defineDefaultCommands(repl) {
action: function() {
this.outputStream.write('Clearing context...\n');
this.bufferedCommand = '';
resetContext();
this.resetContext(true);
this.displayPrompt();
}
});