使用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
获取自定义标记打印?我已经搜索过高低,但没有发现任何特定于此问题的内容。
谢谢!
答案 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}}