Disabling Java class through printer and Clojure reader

I have a Java class Vector2that I would like to convince to "play perfectly" with a Clojure reader.

(def a (vec2 1 2))
(print-str a)
=> "#<Vector2 [1 2]>"

Ideally, I would like the class to print in a form that is read by a Clojure reader. that is, I would like the following to return correctly:

(= a (read-string (print-str a)))

What is the best way to achieve this round trip capability?

+5
source share
1 answer

You need to provide print-dupand print-methodMultimethods for your class / type.

Check out core.clj

Example:

(import 'java.util.Hashtable)
(defmethod print-method Hashtable [x writer] 
      (binding [*out* writer] 
         (print (let [h  (gensym)] 
                 `(let [~h (Hashtable.)] 
                     ~@(map (fn [i] 
                               `(.put ~h ~(str "\"" (.getKey i) "\"") ~(.getValue i)  ) ) x) ~h)))  ))
(def a (Hashtable.))
(.put a "a" 1)
(.put a "b" 2)
(= a (eval (read-string (print-str a))))
+5
source

All Articles