2013-03-02 4 views
6

В Clojure 1.5.0, как я могу предоставить пользовательский довольно-принтер для моего собственного типа записи, определенный с defrecord.довольно-печатная запись с использованием пользовательского метода в Clojure

(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 также использовать мой cutsom принтер (который теперь должен просто красивые отпечатки, что находится в поле a в записи для целей иллюстрации).

ответ

8

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) 
+0

Просто оставить это здесь, потому что именно поэтому я приехал сюда: 'функция pprint-myrecord' должны написать' * из * ', не возвращает строку. – pascal

0

Может быть, не идеальный, но я не нашел лучше, чем pr и pr-str.

Пример РЕПЛ сессия:

(ns my-ns) 

    (defprotocol Foo 
    (bazfn [this])) 

    (defrecord Bar [a] 
    Foo 
    (bazfn [this] 123)) 


    (pr-str (Bar. "ok")) ;;=> "#my_ns.Bar{:a \"ok\"}" 
    (pr (Bar. "ok"))  ;; prints the same as above