While working on hosting Dojo within Node I arrived at a neat solution to isolate the Dojo code from Node itself: evaluate it in a new context. Here’s how it’s done.

var sandbox = {};
process.binding("evals").Script.runInNewContext('this["-eval-"] = function(code){ eval(code); };', sandbox);

runInNewContext evaluates the code in a separate JavaScript context, sandboxed within our sandbox object. We then define this["-eval-"] to call the eval method from the context. This exposes the -eval- method on the sandbox.

We can call it:

sandbox["-eval-"]('this.foo = function(){ return "bar"; };');
require("sys").puts(sandbox.foo());
// bar

Unfortunately declaring global variables inside the context won’t cause them to be set on the sandbox, so this doesn’t work:

sandbox["-eval-"]('baz = function(){ return "thud"; };');
require("sys").puts(sandbox.baz());
// TypeError: Object #<an Object> has no method 'baz'

Same for accessing foo as a global:

sandbox["-eval-"]('this.baz = foo');
// ReferenceError: foo is not defined

I’m not quite sure why this is the case, global variables are treated a bit differently within the context.

One response