문제

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