Да, вам нужно определить для него собственную реализацию метода печати:
(defmethod print-method Xyz [obj writer]
(.write writer (.getXyz obj)))
Вы должны заменить (.getXyz obj)
любой логикой, которую вы хотите для того, что будет напечатано.
Теперь будет лучше, если вы предоставите одну логику для печати в удобочитаемом для человека виде и одну для печати в виде, который может быть прочитан. Таким образом, print
будет печататься в удобочитаемом виде, а pr
будет печататься так, как вы сможете прочитать его с помощью своего пользовательского ридера.
(defmethod print-method Xyz [obj writer]
(if *print-readably*
(.write writer (str "#xyz/builder " "\"" (.getXyz obj) "\""))
(.write writer (.getXyz obj))))
Когда *print-readably*
истинно, вы хотите печатать машиночитаемым способом, чтобы edn/read-string
мог прочитать его снова.
Вот полный пример, я использовал StringBuilder вместо Xyz, так как это было удобно, и по умолчанию он печатает как местоположение памяти объекта (то, что вы сказали, выглядело как хеш), как и то, что вы спрашивали.
(defn getXyz [str]
(StringBuilder. str))
(defn custom-readers []
{'xyz/builder getXyz})
(defn getSomeObj
[]
(edn/read-string
{:readers (custom-readers)}
"{\"version\" \"1.0\"
\"xyz\" #xyz/builder \"testString\"}"))
(defmethod print-method StringBuilder [obj writer]
(if *print-readably*
(.write writer (str "#xyz/builder " "\"" (.toString obj) "\""))
(.write writer (str "The xyz is: " (.toString obj)))))
(getSomeObj)
;; => {"version" "1.0", "xyz" #xyz/builder "testString"}
(pr-str (getSomeObj))
;; => "{\"version\" \"1.0\", \"xyz\" #xyz/builder \"testString\"}"
(print-str (getSomeObj))
;; => "{version 1.0, xyz The xyz is: testString}"
person
Didier A.
schedule
29.11.2019