Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I capture the standard output of clojure?

Tags:

clojure

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

like image 336
yazz.com Avatar asked Mar 29 '11 11:03

yazz.com


3 Answers

(with-out-str (println "this should return as a string"))
like image 56
Michiel de Mare Avatar answered Nov 01 '22 15:11

Michiel de Mare


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.

like image 44
Alex Stoddard Avatar answered Nov 01 '22 16:11

Alex Stoddard


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.

like image 3
sanityinc Avatar answered Nov 01 '22 14:11

sanityinc