在 prepl 会话中,Clojure 的警告信息将保留在缓冲区中,除非客户端显式刷新,否则不会发送给客户端。
以下是一个使用 netcat
的 prepl 会话示例(以 ;;
开头的行表示来自 prepl 服务器的响应)
$ clojure -X clojure.core.server/start-server :name prepl :port 5555 :accept clojure.core.server/io-prepl :server-daemon false &
$ nc localhost 5555
(set! *warn-on-reflection* true)
;; {:tag :ret, :val "true", :ns "user", :ms 2, :form "(set! *warn-on-reflection* true)"}
(.toString (identity "foo"))
;; {:tag :ret, :val "\"foo\"", :ns "user", :ms 4, :form "(.toString (identity \"foo\"))"}
(binding [*out* *err*] (flush))
;; {:tag :err, :val "Reflection warning, NO_SOURCE_PATH:2:1 - reference to field toString can't be resolved.\n"}
;; {:tag :ret, :val "nil", :ns "user", :ms 4, :form "(binding [*out* *err*] (flush))"}
(defn identity [x] x)
;; {:tag :ret, :val "#'user/identity", :ns "user", :ms 3, :form "(defn identity [x] x)"}
(binding [*out* *err*] (flush))
;; {:tag :err, :val "WARNING: identity already refers to: #'clojure.core/identity in namespace: user, being replaced by: #'user/identity\n"}
;; {:tag :ret, :val "nil", :ns "user", :ms 2, :form "(binding [*out* *err*] (flush))"}
这似乎是由 prepl 的 *err*
PrintWriter 未启用 autoFlush
以及 Clojure 的大部分警告都没有显式刷新导致的。
这是一个需要解决的问题吗?或者这是一个预期的行为,客户端有责任及时刷新错误流吗?