当 print-dup 为 true 时,如果被打印的对象有一个只包含 :tag 键的 metadata 映射表,打印机会将其渲染为 "^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 时打印出完整的 metadata 映射表来修复此问题。补丁还包括对此情况的测试。
(链接:1) https://github.com/ztellman/sleight https://github.com/ztellman/riddley