我使用emacs,slim和sbcl。当发生条件时将我扔到调试器中时,如何限制输出的大小?我已经弄清楚了*print-length*
和*print-level*
,但是长字符串或多行字符串怎么办?说,
(defun monkeys (length)
"Generate a random string"
(with-output-to-string (out)
(dotimes (i length)
(write-char
(code-char
(let ((c (random 27)))
(if (zerop c)
(if (zerop (random 5)) 10 32)
(+ 95 c)))) out))))
(1+ (monkeys 10000)) ; drop into debugger
CL打印机是一件复杂而奇妙的事情,我已经忘记了我以前所了解的大多数知识,因此,这个答案很可能是错误的。
没有简单的方法来控制大字符串的打印:您可以使用*print-array*
控制大的常规数组的打印,但是其中有一个特殊的字符串例外。
然后有一个坏方法和一个不太坏的方法。
不好的方法:在*print-array*
上定义一个方法。我认为您可以对字符串执行此操作,但是如果执行此操作,则只要要打印字符串,就会调用您的方法,因此最好确保它是正确的。可能的确保方式是确保它侦听某个变量,并且除非该变量要求它执行某项操作,否则它仅使用print-object
过渡到可能是正确的实现。
不太麻烦的方法:使用漂亮打印机的分派表执行所需的操作。这不太麻烦(甚至可能还不错),因为它不会改变print-object
为false时会发生的情况,并且您也可以随时将原始表放回原处。
这里是一个玩具尝试这样做。 警告:我没有花足够的时间去思考它如何与所有打印机控制设置交互,并且正如我所说的,我已经忘记了很多细节,因此在许多情况下几乎可以肯定这是不正确的。因此,请勿在生产代码中使用此代码,但类似的内容可能足以用于调试目的,其中打印的内容只能告诉您足够的信息来调试程序,而且不必在每个细节上都正确。
call-next-method
现在:
*print-pretty*
长话短说,可以使用sbcl (defvar *toy-print-pprint-dispatch*
;; a copy of the default pprint dispatch table
(copy-pprint-dispatch nil))
(defvar *longest-string*
;; the longest string we try to print properly
40)
(defun write-string-maybe (stream string)
;; Maybe write a string.
(check-type string string "not a string")
(cond (*print-readably*
(write string :stream stream :pretty nil :readably t))
((<= (length string) *longest-string*)
(write string :stream stream :pretty nil))
(t
;; pretty sure this is wrong as it should defang the string
;; at least
(print-unreadable-object (string stream :type t)
(write-string string stream :start 0 :end *longest-string*)
(write-string "..." stream )))))
(set-pprint-dispatch 'string 'write-string-maybe 0 *toy-print-pprint-dispatch*)
(defun monkeys (length)
"Generate a random string"
(with-output-to-string (out)
(dotimes (i length)
(write-char
(code-char
(let ((c (random 27)))
(if (zerop c)
(if (zerop (random 5)) 10 32)
(+ 95 c)))) out))))
(defun test-it ()
(let ((*print-pretty* t)
(*print-pprint-dispatch* *toy-print-pprint-dispatch*))
(print (monkeys *longest-string*))
(print (monkeys (* *longest-string* 2)))
(let ((*print-pretty* nil))
(print (monkeys (* *longest-string* 2))))
(values)))
。从SBCL源代码:
> (test-it)
"pcbkhetnbanuvsvsvqobbqlcodnafmpgdnlku pf"
#<simple-base-string vehgsgnjxixyp`hq`wcwwskmcg`r`jdplcsbdxvo...>
"tp ixreii ixpeb`pgrvcobcbysgikylabidrierclrijo`edugnerlslj srryypbpravomcuxupynf"
长话长说,我从未想到过看源代码。但是,感谢@tfb的回答,我至少有了一个起点。因此,我继续阅读了漂亮打印机的调度表,并且,为了了解调度函数的外观,我检查了*print-vector-length*
的默认调度函数是:
(defparameter *print-vector-length* nil
"Like *PRINT-LENGTH* but works on strings and bit-vectors.
Does not affect the cases that are already controlled by *PRINT-LENGTH*")
给出'string
。我在SBCL源代码中搜索了它,并在此过程中找到了必要的参数。