Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Round-tripping a Java class through the Clojure printer and reader

I have a Java class Vector2 that I'd like to persuade to "play nicely" with the Clojure reader.

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

Ideally I'd like the class to print out in a form that can be read by the Clojure reader. i.e. I'd like the following to return true:

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

What is the best way of achieving this round-tripping capability?

like image 519
mikera Avatar asked Feb 22 '13 10:02

mikera


1 Answers

You need to provide print-dup and print-method multimethods for your class/type.

Check out core.clj

Ex:

(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))))
like image 180
Ankur Avatar answered Sep 25 '22 05:09

Ankur