在Clojure 1.5.0中,如何为我自己的记录类型提供自定义漂亮的打印机,用defrecord定义。
(defrecord MyRecord [a b])
(defmethod print-method MyRecord [x ^java.io.Writer writer]
(print-method (:a x) writer))
(defmethod print-dup MyRecord [x ^java.io.Writer writer]
(print-dup (:a x) writer))
(println (MyRecord. 'a 'b)) ;; a -- OK
(clojure.pprint/pprint (MyRecord. 'a 'b)) ;; {:a a, :b b} -- not OK, I want a
我希望clojure.pprint/pprint
也可以使用我的cutom打印机(现在,它应该只是打印出记录字段a
中的任何内容,以便进行说明)。
答案 0 :(得分:9)
clojure.pprint
命名空间使用不同的调度机制,然后使用clojure.core
打印功能。您需要使用with-pprint-dispatch
来自定义pprint。
(clojure.pprint/with-pprint-dispatch print ;;Make the dispatch to your print function
(clojure.pprint/pprint (MyRecord. 'a 'b)))
要自定义简单调度程序,请添加以下内容:
(. clojure.pprint/simple-dispatch addMethod MyRecord pprint-myrecord)
答案 1 :(得分:3)
这一直非常混乱,问题的不同部分的正确答案遍布各地,所以我把它们放在一起,希望有人可以节省一些时间。
我详细介绍了为defrecord定义多方法print-method
,print-dup
和simple-dispatch
以及设置动态变量*print-pprint-dispatch*
和*print-dup*
的所有排列方式。我在pr
和pprint
中放了一个示例defrecord,并提出了以下流程图。现在我可以立刻看到一切,这是有道理的。
排列代码是蛮力;我只是看了一下输出并直接创建了Visio图。没什么好看的。
(ns print-test
(:require [clojure.pprint :as pp]))
(defrecord tr000 [val])
(defrecord tr001 [val])
(defrecord tr010 [val])
(defrecord tr011 [val])
(defrecord tr100 [val])
(defrecord tr101 [val])
(defrecord tr110 [val])
(defrecord tr111 [val])
;;(defmethod print-method tr000 [obj writer] (.write writer "tr000 print-method"))
;;(defmethod print-dup tr000 [obj writer] (.write writer "tr000 print-dup"))
;;(defmethod pp/simple-dispatch tr000 [obj] (.write *out* "tr000 simple-dispatch"))
;;(defmethod print-method tr001 [obj writer] (.write writer "tr001 print-method"))
;;(defmethod print-dup tr001 [obj writer] (.write writer "tr001 print-dup"))
(defmethod pp/simple-dispatch tr001 [obj] (.write *out* "tr001 simple-dispatch"))
;;(defmethod print-method tr010 [obj writer] (.write writer "tr010 print-method"))
(defmethod print-dup tr010 [obj writer] (.write writer "tr010 print-dup"))
;;(defmethod pp/simple-dispatch tr010 [obj] (.write *out* "tr010 simple-dispatch"))
;;(defmethod print-method tr011 [obj writer] (.write writer "tr011 print-method"))
(defmethod print-dup tr011 [obj writer] (.write writer "tr011 print-dup"))
(defmethod pp/simple-dispatch tr011 [obj] (.write *out* "tr011 simple-dispatch"))
(defmethod print-method tr100 [obj writer] (.write writer "tr100 print-method"))
;;(defmethod print-dup tr100 [obj writer] (.write writer "tr100 print-dup"))
;;(defmethod pp/simple-dispatch tr100 [obj] (.write *out* "tr100 simple-dispatch"))
(defmethod print-method tr101 [obj writer] (.write writer "tr101 print-method"))
;;(defmethod print-dup tr101 [obj writer] (.write writer "tr101 print-dup"))
(defmethod pp/simple-dispatch tr101 [obj] (.write *out* "tr101 simple-dispatch"))
(defmethod print-method tr110 [obj writer] (.write writer "tr110 print-method"))
(defmethod print-dup tr110 [obj writer] (.write writer "tr110 print-dup"))
;;(defmethod pp/simple-dispatch tr110 [obj] (.write *out* "tr110 simple-dispatch"))
(defmethod print-method tr111 [obj writer] (.write writer "tr111 print-method"))
(defmethod print-dup tr111 [obj writer] (.write writer "tr111 print-dup"))
(defmethod pp/simple-dispatch tr111 [obj] (.write *out* "tr111 simple-dispatch"))
(def t000 (->tr000 10))
(def t001 (->tr001 20))
(def t010 (->tr010 30))
(def t011 (->tr011 40))
(def t100 (->tr100 50))
(def t101 (->tr101 60))
(def t110 (->tr110 70))
(def t111 (->tr111 80))
(def recs [t000 t001 t010 t011 t100 t101 t110 t111])
(def dt (java.time.LocalTime/now))
(defmethod print-dup java.time.LocalTime [obj writer] (.write writer "datetime_dup"))
(println "(pr ...) outputs the following")
(doseq [rec recs]
(doseq [prppd [nil #(.write *out* "pprint-dispatch with" %)]]
(binding [pp/*print-pprint-dispatch*
(if prppd #(.write *out* (str "pprint-dipatch-with" %))
pp/*print-pprint-dispatch*)]
(doseq [pd [false true]]
(binding [*print-dup* pd]
(let [ppdstr (format "%6s" (boolean pp/*print-pprint-dispatch*))
dupstr (format "%6s" *print-dup*)
outstr (pr-str rec)]
(binding [*print-dup* false]
(println ppdstr dupstr ":" outstr))))))))
(println "\n(pprint ...) outputs the following")
(doseq [rec recs]
(doseq [prppd [false true]]
(binding [pp/*print-pprint-dispatch*
(if prppd #(.write *out* (str "pprint-dipatch-with" %))
pp/*print-pprint-dispatch*)]
(doseq [pd [false true]]
(binding [*print-dup* pd]
(let [outstr
(with-out-str
(pp/pprint {:ppdstr prppd
:dupstr pd
:dt dt
:strobj rec}))]
(binding [*print-dup* false]
(println outstr "\n"))))))))
答案 2 :(得分:0)