当 print-dup 为 true 时,如果正在打印的对象具有仅含 :tag
键的元数据映射,打印机将其渲染为 "^value"。在某些情况下,这可能会导致 IllegalArgumentException,如果您尝试将打印的字符串读回。例如:
user=> (read-string (let [ge (with-meta (gensym) {:tag Object})] (binding [*print-dup* true] (pr-str ge)))) IllegalArgumentException Metadata 必须是 Symbol,Keyword,String 或 Map clojure.lang.LispReader$MetaReader.invoke (LispReader.java:732)
这导致 sleight/riddley 对 (case) 宏的处理出现问题,因为它在返回的表单中包含 gensym 时丢弃了类型提示。当 sleight 尝试从 riddley 重新序列化宏展开的 (case) 表达式时,就像上面演示的那样会失败。例如:
user=> (read-string (binding [*print-dup* true] (pr-str (macroexpand '(case 1 1 1))))) user=> IllegalArgumentException Metadata 必须是 Symbol,Keyword,String 或 Map clojure.lang.LispReader$MetaReader.invoke (LispReader.java:732)
附带的补丁通过使 core_print.clj 的 print-meta 在 print-dup 为 true 时始终打印完整的元数据映射来解决此问题。补丁还包括对此情况的测试。
(链接:1) https://github.com/ztellman/sleight https://github.com/ztellman/riddley