0

I want to retrieve the string, generated by write for further processing without doing any actual output, but write seems always to also output into the REPL

CL-USER>(let ((err-string (write (make-instance 'error) :stream nil)))
          (do-awesome-stuff-with-string err-string))
<ERROR> ;;this is the printing I want to get rid of
"awesome-result"

Why does write still outputs into the REPL, and how do I get rid of that?

Sim
  • 4,199
  • 4
  • 39
  • 77
  • Some answers have addressed how you might get _a_ string representation of the error object along the lines of `#`, like you'd see if you simply print it, you might also be interested in the functions [simple-condition-format-control and simple-condition-format-arguments](http://www.lispworks.com/documentation/HyperSpec/Body/f_smp_cn.htm)), which you could use to reconstruct the message that you'd typically see if the error was signaled. This only works for subclasses of `simple-condition` though, so it's a not quite as widely applicable. – Joshua Taylor Oct 13 '13 at 12:16
  • @JoshuaTaylor I was looking for a general approach – Sim Oct 14 '13 at 18:47
  • and that's why I didn't post it as an answer. I still expect that someone else who finds this question might find that information useful, depending on what they're trying to do. – Joshua Taylor Oct 14 '13 at 18:51

2 Answers2

6

You can use with-output-to-string for this. Here's an example:

(flet ((do-awesome-stuff-with-string (string)
         (concatenate 'string string " is awesome!")))
  (let ((err-string (with-output-to-string (s)
                      (write (make-instance 'error) :stream s))))
    (do-awesome-stuff-with-string err-string)))
;; => "#<ERROR {25813951}> is awesome!"

Here's here's the HyperSpec entry on with-output-to-string.

The reason (write (make-instance 'error) :stream nil) doesn't work is that the :stream argument to write is a stream designator and in that context nil is shorthand for *standard-output*. (The fact that format instead takes nil to mean that it should return a string is a common point of confusion).

jbm
  • 2,575
  • 16
  • 15
3

Keep in mind that portably errors are made with MAKE-CONDITION. The standard does not say that errors are CLOS classes, so MAKE-INSTANCE might not work in some implementations.

There are two simple ways to get a string:

a) a textual description:

CL-USER 15 > (princ-to-string (make-condition 'error))
"The condition #<ERROR 4020311270> occurred"

b) the error object printed:

CL-USER 16 > (prin1-to-string (make-condition 'error))
"#<ERROR 402031158B>"
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346