如何使用pprint格式化多行数据?

Ray*_*yne 16 clojure pprint

pprint的文档有点像砖墙.如果你打印一张地图,它会出现在一行上,如下所示:{:a "b", :b "c", :d "e"}.相反,我想像这样打印,可选择使用逗号:

{:a "b"
 :b "c"
 :d "e"}
Run Code Online (Sandbox Code Playgroud)

如何用pprint做到这一点?

int*_*ted 13

您可以设置*print-right-margin*绑定:

Clojure=> (binding [*print-right-margin* 7] (pprint {:a 1 :b 2 :c 3}))
{:a 1,
 :b 2,
 :c 3}
Run Code Online (Sandbox Code Playgroud)

不完全是你想要的,但它可能就足够了?

顺便说一句,最好的方法来解决这个问题 - 至少我采取的方法是使用

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
Run Code Online (Sandbox Code Playgroud)

嗯......怎么with-pretty-writer*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
Run Code Online (Sandbox Code Playgroud)

好的,*print-right-margin*听起来很有希望......

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
Run Code Online (Sandbox Code Playgroud)

此外,这是非常有用的信息:

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
Run Code Online (Sandbox Code Playgroud)

无论如何 - 也许你甚至已经知道了 - 如果你真的想要自定义pprint工作方式,你可以proxy clojure.contrib.pprint.PrettyWriter通过绑定它来传递它*out*.PrettyWriter类非常庞大且令人生畏,因此我不确定这是否是您最初对"砖墙"评论的意思.


laz*_*zy1 6

我不认为你能做到这一点,你可能需要自己编写,例如:

(defn pprint-map [m]
  (print "{")
  (doall (for [[k v] m] (println k v)))
  (print "}"))
Run Code Online (Sandbox Code Playgroud)