简体   繁体   English

将clojure的* out *重定向到core.async通道

[英]Redirecting clojure's *out* to a core.async channel

I'm trying to make all print statements in a clojure program put their strings on a core.async channel. 我试图让clojure程序中的所有print语句都将它们的字符串放在core.async通道上。 Is there a way I can do this? 有没有办法可以做到这一点?

(I'm trying to get cljsbuild to send its compiler messages to a frontend.) (我正在尝试让cljsbuild将其编译器消息发送到前端。)

(def is (java.io.PipedInputStream.))
(def os (java.io.PipedOutputStream. is))

(def channel (chan))

(.start (Thread. (fn []
                   (let [buffer (byte-array 1024)]
                     (while true
                       (let [n (.read is buffer 0 1024)]
                         (>!! channel (vec (take n buffer)))))))))

(binding [*out* (java.io.OutputStreamWriter. os)]
  (println "Hello, world!"))

gfredericks gave me this reference in the #clojure irc. gfredericks在#clojure irc中给了我这个参考。 He recommended I adapt what nREPL does: 他建议我适应nREPL的作用:

(defn- session-out
  "Returns a PrintWriter suitable for binding as *out* or *err*.  All of
   the content written to that PrintWriter will (when .flush-ed) be sent on the
   given transport in messages specifying the given session-id.
   `channel-type` should be :out or :err, as appropriate."
  [channel-type session-id transport]
  (let [buf (clojure.tools.nrepl.StdOutBuffer.)]
    (PrintWriter. (proxy [Writer] []
                    (close [] (.flush ^Writer this))
                    (write [& [x ^Integer off ^Integer len]]
                      (locking buf
                        (cond
                          (number? x) (.append buf (char x))
                          (not off) (.append buf x)
                          ; the CharSequence overload of append takes an *end* idx, not length!
                          (instance? CharSequence x) (.append buf ^CharSequence x (int off) (int (+ len off)))
                          :else (.append buf ^chars x off len))
                        (when (<= *out-limit* (.length buf))
                          (.flush ^Writer this))))
                    (flush []
                      (let [text (locking buf (let [text (str buf)]
                                                (.setLength buf 0)
                                                text))]
                        (when (pos? (count text))
                          (t/send (or (:transport *msg*) transport)
                                  (response-for *msg* :session session-id
                                                channel-type text))))))
                  true)))

from nREPL source here 来自nREPL来源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM