我是Lisp的新手,我遇到了打印问题。我有一个函数可以打印到标准输出(除其他外)。我想通过另一个函数运行此函数,它仍然运行相同但没有任何东西被打印到标准输出。
这是我的意思的一个简单例子。我有以下两个描述的功能:
(defun does-printing()
(print "This goes to standard output."))
(defun run-other-function (function)
(funcall function)
(values))
这是我运行时会发生的运球,
;; Dribble of #<IO TERMINAL-STREAM> started on 2014-10-05 21:49:49.
#<OUTPUT BUFFERED FILE-STREAM CHARACTER #P"example.out">
[7]> (run-other-function #'does-printing)
"This goes to standard output."
[8]> (dribble)
;; Dribble of #<IO TERMINAL-STREAM> finished on 2014-10-05 21:50:09.
请注意,打印功能仍会打印到标准输出。它希望能够通过run-other-function运行打印时以某种方式抑制此打印。在搜索解决方案时,我已经尝试了许多不同的措辞,但没有任何东西可以达到我想做的目的。
答案 0 :(得分:10)
最简单的解决方案是创建一个空的广播流。
(with-open-stream (*standard-output* (make-broadcast-stream))
(call-some-function-1)
...
(call-some-function-n))
如果广播流没有组件流,则将丢弃所有输出。上面将*standard-output*
绑定到这样的流。这不会消耗任何数据,而且是可移植的。
答案 1 :(得分:2)
您只需将标准输出重定向到某个地方即可。例如,如果您的操作系统中有一个,则进入/ dev / null。看起来非常惯用的UNIX方式输出抑制。
请注意,您不应将其设置为NIL,因为在这种情况下,print会发出信号类型错误。
(defun does-printing()
(print "This goes to standard output."))
(defun run-other-function (function)
(with-open-file (*standard-output*
"/dev/null"
:direction :output
:if-exists :supersede)
(funcall function)
(values)))
CL-USER> (run-other-function #'does-printing)
; No value
其他选项(可能更好)是使用with-output-to-string
,因此您可以捕获此输出值或忽略它。认为它更好,因为如果我们不需要它,为什么要做IO,而且它必须适用于任何操作系统。
(defun run-other-function (function)
(with-output-to-string (*standard-output*
(make-array '(0)
:element-type 'base-char
:fill-pointer 0 :adjustable t))
(funcall function)
(values)))
如果你做了很多,你可以把它包装成宏甚至功能,用来代替funcall。
(defun does-printing()
(print "This goes to standard output.")
"My result")
(defun funcall-with-no-output (fn)
(with-output-to-string (*standard-output*
(make-array '(0)
:element-type 'base-char
:fill-pointer 0 :adjustable t))
(funcall fn)))
CL-USER> (funcall-with-no-output #'does-printing)
"My result"
但是我认为宏对于这种情况会更普遍和惯用(可能是我错了)。
(defmacro with-suppressed-output (&body body)
`(with-output-to-string (*standard-output*
(make-array '(0)
:element-type 'base-char
:fill-pointer 0 :adjustable t))
,@body))
因此,您可以在with-suppressed-output
中调用多个表单。