调试输出中字符串的限制长度

问题描述 投票:3回答:2

我使用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
common-lisp sbcl slime
2个回答
1
投票

CL打印机是一件复杂而奇妙的事情,我已经忘记了我以前所了解的大多数知识,因此,这个答案很可能是错误的。

没有简单的方法来控制大字符串的打印:您可以使用*print-array*控制大的常规数组的打印,但是其中有一个特殊的字符串例外。

然后有一个坏方法和一个不太坏的方法。

不好的方法:在*print-array*上定义一个方法。我认为您可以对字符串执行此操作,但是如果执行此操作,则只要要打印字符串,就会调用您的方法,因此最好确保它是正确的。可能的确保方式是确保它侦听某个变量,并且除非该变量要求它执行某项操作,否则它仅使用print-object过渡到可能是正确的实现。

不太麻烦的方法:使用漂亮打印机的分派表执行所需的操作。这不太麻烦(甚至可能还不错),因为它不会改变print-object为false时会发生的情况,并且您也可以随时将原始表放回原处。

这里是一个玩具尝试这样做。 警告:我没有花足够的时间去思考它如何与所有打印机控制设置交互,并且正如我所说的,我已经忘记了很多细节,因此在许多情况下几乎可以肯定这是不正确的。因此,请勿在生产代码中使用此代码,但类似的内容可能足以用于调试目的,其中打印的内容只能告诉您足够的信息来调试程序,而且不必在每个细节上都正确。

call-next-method

现在:

*print-pretty*

0
投票

长话短说,可以使用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源代码中搜索了它,并在此过程中找到了必要的参数。

© www.soinside.com 2019 - 2024. All rights reserved.