Clojure: redirecting output to a file
In a scripting language, you often run scripts from a command line and print things to STDOUT. For long output you can redirect it to a file via shell-redirection ($ foo.rb > foo.txt).
But if you're using Clojure for ad-hoc scripting, you're probably sitting in a REPL, not running from a command line. REPLs generally don't have shell-redirection. Printed output just gets dumped into your REPL. This can be annoying. (After a good 10,000 lines of output into a REPL buffer, Emacs starts to lag.)
But you can write a macro to handle this easily enough.
(use 'clojure.contrib.duck-streams)
(defmacro redir [filename & body]
`(spit ~filename (with-out-str ~@body)))
Then:
user> (redir "foo.txt" (foo) (bar) (baz))
Now whatever (foo) and friends would've printed to STDOUT will instead go to foo.txt. I've found this somewhat useful at work lately.
Edit: better version via Graham Fawcett:
(defmacro redir [filename & body]
`(binding [*out* (writer ~filename)] ~@body))

6 Comments
Ha, neat trick. Thanks. I'm sure this will work well enough in any Lisp dialect language :)
Yeah I'm pretty sure Common Lisp can do it. Any language that lets you dynamically bind the STDOUT handle to some sort of string-writer will do it. You could probably even do it in Ruby with blocks.
Correct me if I'm wrong, but doesn't your example buffer all of the output of the body (into a string), and then push the string out to a file?
Why not just dynamically bind
*out*to the opened file?Right, good point.
You should make sure that the output stream is flushed and closed. The later version does not do this, I suggest this instead:
Speak your Mind
Preview