What's a good toString method for a deftype'd object in clojure
(deftype Bag [state]
Object
(toString [bag]
(str "Bag???" state)))
I want the toString to look something like
clojure.core=> (def b (Bag. {:apples 1 :bannanas 4}))
#'clojure.core/b
clojure.core=> (str b)
"BAG: {:apples 1 :bannanas 4}"
What is a nice clojurey way of representing that information? Is
"Bag/{:k :v}开发者_如何学C"
better? How does the community do you call your toStrings?
Depending on exactly what you're trying to do, the simplest way is to use defrecord
:
user=> (defrecord Bag [state]) user.Bag user=> (def b (Bag. :foo)) #'user/b user=> b #:user.Bag{:state :foo}
Though what you see above is from pr
, not str
:
user=> (str b) "user.Bag@53e935f4" user=> (prn b) #:user.Bag{:state :foo} nil
So we just make a change:
user=> (defrecord Bag [state] Object (toString [bag] (pr-str bag))) user.Bag user=> (def b (Bag. :foo)) #'user/b user=> (str b) "#:user.Bag{:state :foo}" user=> (.toString b) "#:user.Bag{:state :foo}"
Now, if the above is not suitable, then next option would be to add a new method to the print-method
multi-method. Google around for details on that.
Aside: Using defrecord
should generally be preferred over deftype
unless you're doing something very low-level.
The following is for deftype
.
user=> (deftype Bag [state]
Object
(toString [_]
(str "BAG: " (pr-str state))))
user.Bag
user=> (def b (Bag. {:apples 1 :bannanas 4}))
#'user/b
user=> (str b)
"BAG: {:bannanas 4, :apples 1}"
精彩评论