16

I have some printlns I need to capture from a Clojure program and I was wondering how I could capture the output?

I have tried:

(binding [a *out*]
    (println "h")
    a
)

: but this doesn't work

yazz.com
  • 57,320
  • 66
  • 234
  • 385

3 Answers3

37
(with-out-str (println "this should return as a string"))
Michiel de Mare
  • 41,982
  • 29
  • 103
  • 134
8

Just to expand a little on Michiel's answer, when you want to capture output to a file you can combine with-out-str with spit.

When you don't want to build up a huge string in memory before writing it out then you can use with-out-writer from the clojure.contrib.io library.

with-out-writer is a macro that nicely encapsulates the correct opening and closing of the file resource and the binding of a writer on that file to *out* while executing the code in its body.

Alex Stoddard
  • 8,244
  • 4
  • 41
  • 61
3

Michiel's exactly right. Since I can't add code in a comment on his answer, here's what with-out-str does under the covers, so you can compare it with your attempt:

user=> (macroexpand-1 '(with-out-str (println "output")))
(clojure.core/let [s__4091__auto__ (new java.io.StringWriter)]
  (clojure.core/binding [clojure.core/*out* s__4091__auto__]
    (println "output")
    (clojure.core/str s__4091__auto__)))

Your code was binding the existing standard output stream to a variable, printing to that stream, and then asking the stream for its value via the variable; however, the value of the stream was of course not the bytes that had been printed to it. So with-out-str binds a newly created StringWriter to *out* temporarily, and finally queries the string value of that temporary writer.

dexterous
  • 146
  • 2
  • 10
sanityinc
  • 15,002
  • 2
  • 49
  • 43