Как я могу избежать печати хэш-кода объекта при чтении файла EDN в объекты Java с помощью clojure

Я определил считыватель EDN для пользовательских тегов, который создает новый объект при появлении пользовательских тегов. Я использую edn/read-string для чтения данных EDN.

(defn getXyz [str]
    (.getXyz (XyzBuilder.) str)
)

(defn custom-readers []
    {'xyz/builder getXyz}
)

(defn getSomeObj
    [filename myEdnFile]
    (edn/read-string
        {:readers custom-readers}
        (slurp myEdnFile))
)

Мой файл EDN

{
   "version" "1.0"
   "xyz" #xyz/builder "testString"
}

Когда я печатаю вывод getSomeObj из java, он печатает следующий вывод

{"version" "1.0", "Xyz" #object[com.java.sample.Xyz 0x6731787b "Xyz [type=type_1]"]}

Я хочу избежать получения хэш-кода объекта (например, #object[com.java.sample.Xyz 0x6731787b) в возвращаемой строке. Есть ли способ добиться этого?


person ppp456878    schedule 29.11.2019    source источник


Ответы (1)


Да, вам нужно определить для него собственную реализацию метода печати:

(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