質問

I am trying to print a sequence such that neither the whole sequence is printed on one line, nor is each element of the sequence printed on its own line. E.g.

[10 11 12 13 14 15 16 17 18 19
 20 21 22 23 24 25 26 27 28 29]

I found pprint-newline in the documentation which indicates that allows me to determine how the newline gets printed. Unfortunately, I cannot find any examples on how it is to be used in conjunction with pprint, and the doc string doesn't to offer much insight:

-------------------------
clojure.pprint/pprint-newline
([kind])
  Print a conditional newline to a pretty printing stream. kind specifies if the 
newline is :linear, :miser, :fill, or :mandatory. 

This function is intended for use when writing custom dispatch functions.

Output is sent to *out* which must be a pretty printing writer.

pprint specifies an optional second argument for the writer, which is by default set to *out*. However, I am not sure how to 'send' pprint-writer to *out* in this case, e.g. something like the example below doesn't appear to work

(clojure.pprint/pprint [1 2 3 4] (*out* (clojure.pprint/pprint-newline :miser)))
役に立ちましたか?

解決

While Guillermo explained how to change the dispatch for pretty-printing in general, if all you want to do is printing one collection differently, that's possible, too.

For example, using cl-format (after (use '[clojure.pprint :as pp)):

(binding [pp/*print-pretty* true
          pp/*print-miser-width* nil
          pp/*print-right-margin* 10]
  (pp/cl-format true "~<[~;~@{~a~^ ~:_~}~;]~:>~%" '[foo bar baz quux]))

Set *print-right-margin* as you wish.

You don't have to use format for this. The format directives can be translated to their respective pretty-printer functions, if you want. Explanation of the format string: ~< and ~:> establish a logical block. Inside the block, there are three sections separated by ~;. The first and last section are your prefix and suffix, while the elements are printed in the middle section, using ~@{ and ~}. For each element, the element is printed using ~a, followed by a space, if needed, and a conditional fill-style newline.

(In CL, the format string could be simplified to "~<[~;~@{~a~^ ~}~;]~:@>~%", but that doesn't seem to work in Clojure 1.5.)

他のヒント

As the help says, the function is intended for use for custom dispatch functions.

In order to change the behavior of the pprint for sequences you need to provide a new dispatch function for clojure.lang.ISeq.

The current dispatch function for sequences you can find in clojure/pprint/dispatch.clj

(use-method simple-dispatch clojure.lang.ISeq pprint-list) 
...
(defn- pprint-simple-list [alis]
    (pprint-logical-block :prefix "(" :suffix ")"
      (print-length-loop [alis (seq alis)]
        (when alis
      (write-out (first alis))
      (when (next alis)
        (.write ^java.io.Writer *out* " ")
        (pprint-newline :linear)
        (recur (next alis)))))))    

Since printing is dispatched according to data type overriding seems to be the way to go.

See the source code for ideas.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top