众所周知,您可以使用命令绑定将自定义编写器临时附加到全局变量,例如 out 。例如,这有效:
(let [customWriter (StringWriter.)]
(binding [*out* customWriter]
(println "One line!")
(.toUpperCase (.toString customWriter))))
打印" ONE LINE!\ r \ n"如预期的那样。
我在customWriter中捕获了标准输出。我想对标准错误流做同样的事情。所以我做了:
(let [customWriter (StringWriter.)]
(binding [*err* customWriter]
(try (/ 1 0)
(catch Exception e
(.printStackTrace e)
(.toString customWriter)))))
但它返回一个空字符串,仍然在控制台中打印堆栈跟踪。有趣的是,如果在REPL中尝试 err 和System / err,则它们是不同的实例。
我知道还有另一种方法可以做我想要的,即将自定义PrintWriter传递给异常的printStackTrace方法。但我认为我误解了与 err 相关的一些我需要掌握的东西。
答案 0 :(得分:2)
Java的.printStackTrace
方法对于Clojure的*err*
var的存在是不可知的,所以binding
它不会改变Java的行为。
改为考虑
(use 'clojure.stacktrace)
(try (/ 1 0)
(catch Exception e
(with-out-str (print-stack-trace))))
有关详细信息,请参阅print-stack-trace
的来源,但基本上它使用的是.getStackTrace
方法,然后打印到*out*
,例如,您可以与with-out-str
绑定。