How to stream output of system process in Ruby rake task?

Often time, I use Rake to manage a number of tasks I use often, but I can’t remember the command. It’s part of building tools for yourself to make yourself more productive.

Sometimes, you use rake tasks to run servers, like so:

desc "Start the server"
task :start do
  puts `node app.js`
end

However, that doesn’t work. The child process blocks, and won’t return until the server exits, so that means `puts` never gets a return, and hence never executes. In addition, stdout of the child process running node isn’t connected to the stdout of the parent process running rake. Therefore, you won’t see any output from the server.

Finally, being fed up with the situation, I started looking around on google and stackoverflow, and it’s kind of an elusive question. But I finally have it. It looks like this:

desc "Start the server"
task :start do
  IO.popen("node app.js") { |f| f.each { puts line } }
end

As long as `node app.js` continuously flushes its stdout, we’ll get its output sent to the rake’s stdout. Yay. One less annoying thing to deal with.

[1] Reference: http://stackoverflow.com/questions/1154846/continuously-read-from-stdout-of-external-process-in-ruby

Advertisements

not vs !, and vs &&

It’s always confusing when you have similar methods that have slightly different meaning. What’s the difference between not vs !, and and &&?

The difference between is subtle enough that it might not matter most of the time, but it might bite you in the ass one day. It doesn’t say which is which, this post gives the example of precedence order. But just by experimenting, you can see that it’s and, or, and not that form statements, which can’t be used in arguments

String.new(“hey” || “hello”) #=> “hey”
String.new(nil || “hello”) #=> “hello”
String.new(nil or “hello”) #=> error: can’t used statements in arguments
String.new((nil or “hello”)) #=> “hello” putting it in parens makes it ok, but ugly

tip!