我正在尝试通过Nrepl连接到用Clojure编写的晦涩的开源知识库,该知识库实际上尚未正式支持这种类型的交互。事情进展顺利,但事实证明,响应值包含无效的Clojure令牌,例如“”
通过命令行,交互看起来像这样:
csneps.core.snuser=> (assert! '(Isa Fido Dog))
wft17!: (Isa Fido Dog)
csneps.core.snuser=> (ask '(Isa Fido Dog))
I wonder if wft17!: (Isa Fido Dog)
I know that wft17!: (Isa Fido Dog)
#{wft17!: (Isa Fido Dog)}
当我尝试使用Nrepl时,出现此问题:
my-project.example => (respond-1 "(ask '(Isa Fido Dog))")
RuntimeException Invalid token: wft17!:
clojure.lang.Util.runtimeException (Util.java:221)
respond-1函数如下所示:
(defn respond-1
([text] (respond-1 text df-nrepl-port))
([text nport] (with-open [conn (nrepl/connect :port nport)]
(-> (nrepl/client conn 1000)
(nrepl/message {:op :eval :code text})
(nrepl/response-values)))))
我怀疑问题在于Nrepl尝试在其响应值实现中评估字符串:
https://github.com/nrepl/nrepl/blob/master/src/clojure/nrepl/core.clj
(defn read-response-value
"Returns the provided response message, replacing its :value string
with the result of (read)ing it.
Returns the message unchanged if the :value slot is empty or not a
string."
[{:keys [value] :as msg}]
(if-not (string? value)
msg
(try
(assoc msg :value (read-string value))
(catch Exception e
(throw (IllegalStateException. (str "Could not read response value: " value) e))))))
(defn response-values
"Given a seq of responses (as from response-seq or returned from
any function returned by client or client-session), returns a seq
of values read from :value slots found therein."
[responses]
(->> responses
(map read-response-value)
combine-responses
:value))
我认为最好的选择是知识库开发人员解决问题并实际上支持nrepl交互,但是撇开这一点,我想问一下什么是最佳选择。我应该分叉nrepl来实现转义不良令牌字符的read-response-value,还是用Java而不是Clojure编写一个小的Nrepl客户端,这样我就没有那些限制,然后从本地检索转义的结果,或完全其他?
谢谢!