如何避免在使用 clojure 将 EDN 文件读入 java 对象时打印对象哈希码
How can I avoid printing object hashcode while reading EDN file in to java objects using clojure
我已经为自定义标签定义了 EDN reader,它在出现自定义标签时创建新对象。
我正在使用 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"
}
当我从 java 打印 getSomeObj 的输出时,它会打印以下输出
{"version" "1.0", "Xyz" #object[com.java.sample.Xyz 0x6731787b "Xyz [type=type_1]"]}
我想避免在 return 字符串中获取对象哈希码(即#object[com.java.sample.Xyz 0x6731787b)。有办法实现吗?
是的,您需要为其定义打印方法的自定义实现:
(defmethod print-method Xyz [obj writer]
(.write writer (.getXyz obj)))
您应该将 (.getXyz obj)
替换为您想要打印内容的任何逻辑。
现在,最好提供一种以人类可读方式打印的逻辑,以及一种以可读回方式打印的逻辑。这样 print
将以人类可读的方式打印,而 pr
将以您可以使用自定义 reader.
阅读的方式打印
(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}"
我已经为自定义标签定义了 EDN reader,它在出现自定义标签时创建新对象。 我正在使用 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"
}
当我从 java 打印 getSomeObj 的输出时,它会打印以下输出
{"version" "1.0", "Xyz" #object[com.java.sample.Xyz 0x6731787b "Xyz [type=type_1]"]}
我想避免在 return 字符串中获取对象哈希码(即#object[com.java.sample.Xyz 0x6731787b)。有办法实现吗?
是的,您需要为其定义打印方法的自定义实现:
(defmethod print-method Xyz [obj writer]
(.write writer (.getXyz obj)))
您应该将 (.getXyz obj)
替换为您想要打印内容的任何逻辑。
现在,最好提供一种以人类可读方式打印的逻辑,以及一种以可读回方式打印的逻辑。这样 print
将以人类可读的方式打印,而 pr
将以您可以使用自定义 reader.
(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}"