嵌套结构中defrecord的自定义pprint

时间:2018-03-19 22:14:09

标签: clojure

使用Clojure 1.8.0

我试图在其他默认格式的嵌套结构中使用自定义格式设置defrecord,以便与EDN一起使用,因此我需要一个带标记的表示。如果它在pprint中出现,我可以使用默认值,但我更喜欢自定义的。事实上,我无法pprint显示自定义的一个,而无需设置*print-pprint-dispatch*pr,这会破坏好的换行符等,{{{ 1}}提供。

pprint

user> (defrecord junkrecord [val]) user> (def junk1 (->junkrecord 10)) user> (def junk2 (->junkrecord 20)) user> (pprint {:key1 junk1, :key2 junk2, :key3 (java.time.LocalTime/now)}) {:key1 {:val 10}, :key2 {:val 20}, :key3 #object[java.time.LocalTime 0xbf97341 "15:04:43.487"]} 显示时没有像defrecord对象那样的主题标签,但LocalTime的主题标签是我想要的。 https://dev.clojure.org/jira/browse/CLJ-1890中未提及此问题。

我为defrecord创建了print-method,与defrecord一起使用时效果正常。

(pr ...)

然而,当我通过user> (defmethod print-method junkrecord [obj writer] (.write writer (str "#ThisIsWhatIwant" (.val obj)))) user> (pr junk1) #ThisIsWhatIwant10 运行时,我会丢失缩进,换行符等。

pprint

我能够让它为user> (with-pprint-dispatch pr (pprint {:key1 junk1, :key2 junk2, :key3 (java.time.LocalTime/now)})) {:key1 #ThisIsWhatIwant10, :key2 #ThisIsWhatIwant20, :key3 #object[java.time.LocalTime 0xa908e55 "15:10:09.634"]} 工作,因为它在这方面的行为更像是Java类,但deftype被推荐用于"低级"东西,而不是像deftype这样的域名。

defrecord

我也玩user> (deftype junktype [val]) user> (def junk3 (junktype. 30)) user> (pprint {:key1 junk3, :key2 (java.time.LocalTime/now)}) {:key1 #object[user.junktype 0x54c21b73 "user.junktype@54c21b73"], :key2 #object[java.time.LocalTime 0x20545fc3 "15:17:40.580"]} user> (defmethod print-method junktype [obj writer] (.write writer (str "#ThisIsWhatIwant" (.val obj)))) user> (pprint {:key1 junk3, :key2 (java.time.LocalTime/now)}) {:key1 #ThisIsWhatIwant30, :key2 #object[java.time.LocalTime 0x499bdba8 "15:18:33.230"]} *print-dup*等,但这并没有产生任何效果。

那么在使用(print-dup ...)进行良好格式化时如何为defrecord获取自定义标记打印?我已经搜索过高低,但没有发现任何特定于此问题的内容。

谢谢!

1 个答案:

答案 0 :(得分:0)

我看待它的方式:

它似乎是proposed,但没有让它打破1.8或1.9

设置:

user=> (defrecord foo [val])
user.foo
user=> (def x (->foo 33))
#'user/x

现在

要么删除pprint并使用str或其他一些

user=> (str {:a-foo x})
"{:a-foo #user.foo{:val 33}}"

或者)为您的类型提供自定义调度

user=> (defmethod clojure.pprint/simple-dispatch user.foo [f] (pr f))
#object[clojure.lang.MultiFn 0x401f3c4 "clojure.lang.MultiFn@401f3c4"]

user=> (pprint {:a-foo x :a-goo x :b x :c x :d x :f x})
{:a-foo #user.foo{:val 33},
 :a-goo #user.foo{:val 33},
 :b #user.foo{:val 33},
 :c #user.foo{:val 33},
 :d #user.foo{:val 33},
 :f #user.foo{:val 33}}

为了完整起见 - 阅读:

user=> (clojure.edn/read-string 
         {:readers {'user.foo map->foo}} 
         "{:a-foo #user.foo{:val 33}}")
{:a-foo #user.foo{:val 33}}