How to interact with a node REPL from Ruby

I'm trying to write a Ruby script that interacts with a Node.js REPL. When I do:

i = IO.popen('node', 'r+')
i.write("console.log('hi')")

The write call returns the size of the write. But how do I get back the output of the REPL for processing? I've tried #read, and it does not return the output.

When you pipe things to node, it expects to read a whole script from stdin. To make the above code work, you need to close the input before you can read the output.

i = IO.popen('node', 'r+')
i.write("console.log('hi')")
i.close_write
print i.read   # => hi

Obviously, you need to write all the commands before you can read any output. If you want to interact with the REPL properly, you need to create a PTY. Here's a small example that runs a few commands and prints their outputs.

require 'pty'
require 'expect'

commands = ["console.log('hi')", "var a = 1", "console.log(a)"]

PTY.spawn("node") do |r,w,pid|
  # r is node's stdout/stderr and w is stdin
  r.expect('>')
  commands.each do |cmd|
    puts "Command: " + cmd
    w.puts cmd
    r.expect(/(.*?)\r\n(.*)>/m) {|res| print "Output: " + res[2] }
  end
end

This kind of interaction with a REPL tends to be fragile, though. I don't know what you're trying to do but you might be better server by writing a small JavaScript program that evals your commands and returns the results in some easily-parsed format.