I have a defrecord which is not pprinting exactly the way I want.

When print-dup is true, I want to eliminate any references to the 
namespace, as I want to write out to edn and read it back in, but without 
running eval while doing so, and without exposing the clojure 
implementation details to the user who ventures into reading the edn file.  
This is not for security, just to keep the edn file independent of 
namespaces.  The defrecord I'm printing has references to other defrecords, 
which also have an abbreviated form for edn writing.

When print-dup is false, I just want pprint and pr-str, etc., to show the 
defrecord name with the namespace, then the map, but normal pprint doesn't 
show the defrecord name.

I've resorted to copying most of pprint-map from the clojure source into my 
simple-dispatch.
This seems like overkill, but it gets what I want.

Can someone comment if this is the right way to go about it?  Is there some 
way to call the built-in (but private) pprint-map directly on my defrecord, 
after printing out the class name?


(ns toydb.edn.shapes
  (:require [jfxutils.core :as jfxc]
            toydb.units))

(defrecord Circle [])

(defmethod print-method Circle [c, ^java.io.Writer writer]
  ;; Writes #toydb.shapes.Circle{:key1 val1, :key2 val2} without line-breaks
  (.write writer (str "#"
                  (pr-str Circle)
                  (pr-str (into {} c)))))

(defmethod print-dup Circle [c, ^java.io.Writer writer]
  ;; Writes #Circle{:key1 val1, :key val2} without line-breaks
  (.write writer "#Circle")
  (print-method (into {} c) writer))


(defmethod clojure.pprint/simple-dispatch Circle [c]
  ;; this is copied with minor modification from
  ;;  
https://github.com/clojure/clojure/blob/master/src/clj/clojure/pprint/dispatch.clj
  ;; It seems like overkill to redefine it just to add classname at the 
beginning  
(let [amap (into {} c)]
    (if clojure.core/*print-dup*
      (.write ^java.io.Writer *out* "#Circle")
      (.write ^java.io.Writer *out* (pr-str Circle))) ;; gets 
#namespace.classname
    (clojure.pprint/pprint-logical-block
     :prefix "{" :suffix "}"
     (clojure.pprint/print-length-loop
      [aseq (seq amap)]
      (when aseq
        (clojure.pprint/pprint-logical-block
         (clojure.pprint/write-out (ffirst aseq))
         (.write ^java.io.Writer *out* " ")
         (clojure.pprint/pprint-newline :linear)
;;  *current-length* is private to pprint-base        
;;(set! *current-length* 0) ; always print both parts of the [k v] pair
         (clojure.pprint/write-out (fnext (first aseq))))
        (when (next aseq)
          (.write ^java.io.Writer *out* ", ")
          (clojure.pprint/pprint-newline :linear)
          (recur (next aseq))))))))

























-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to