问题
pprint
's docs are kind of a brick wall. If you pprint a map, it comes out on one line like so: {:a "b", :b "c", :d "e"}
. Instead, I'd like to be pprinted like this, optionally with commas:
{:a "b"
:b "c"
:d "e"}
How would one do that with pprint?
回答1:
You can set the *print-right-margin*
binding:
Clojure=> (binding [*print-right-margin* 7] (pprint {:a 1 :b 2 :c 3}))
{:a 1,
:b 2,
:c 3}
Not exactly what you're looking for, but it might be enough?
BTW, the best way to figure this out —or at least the approach I took— is to use
Clojure=> (use 'clojure.contrib.repl-utils)
Clojure=> (source pprint)
(defn pprint
"Pretty print object to the optional output writer. If the writer is not provided,
print the object to the currently bound value of *out*."
([object] (pprint object *out*))
([object writer]
(with-pretty-writer writer
(binding [*print-pretty* true]
(write-out object))
(if (not (= 0 (.getColumn #^PrettyWriter *out*)))
(.write *out* (int \newline))))))
nil
Hmmrmmm.. what does with-pretty-writer
do to *out*
?
Clojure=> (source clojure.contrib.pprint/with-pretty-writer)
(defmacro #^{:private true} with-pretty-writer [base-writer & body]
`(let [new-writer# (not (pretty-writer? ~base-writer))]
(binding [*out* (if new-writer#
(make-pretty-writer ~base-writer *print-right-margin* *print-miser-width*)
~base-writer)]
~@body
(if new-writer# (.flush *out*)))))
nil
Okay, so *print-right-margin*
sounds promising...
Clojure=> (source clojure.contrib.pprint/make-pretty-writer)
(defn- make-pretty-writer
"Wrap base-writer in a PrettyWriter with the specified right-margin and miser-width"
[base-writer right-margin miser-width]
(PrettyWriter. base-writer right-margin miser-width))
nil
Also, this is pretty informative:
Clojure=> (doc *print-right-margin*)
-------------------------
clojure.contrib.pprint/*print-right-margin*
nil
Pretty printing will try to avoid anything going beyond this column.
Set it to nil to have pprint let the line be arbitrarily long. This will ignore all
non-mandatory newlines.
nil
Anyway —and perhaps you already knew even this— if you really want to customize the way that pprint
works, you can proxy
clojure.contrib.pprint.PrettyWriter
and pass that down by binding it to *out*
. The PrettyWriter class is pretty large and intimidating, so I'm not sure if this was what you originally meant by your "brick wall" comment.
回答2:
I don't think you can do that, you'll probably need to write your own, something like:
(defn pprint-map [m]
(print "{")
(doall (for [[k v] m] (println k v)))
(print "}"))
来源:https://stackoverflow.com/questions/4020186/how-can-i-format-a-map-over-several-lines-with-pprint