2014-10-06 4 views
3

Я довольно новичок в Lisp, и я столкнулся с проблемой печати. У меня есть одна функция, которая выполняет печать на стандартный вывод (между прочим). Затем я хочу запустить эту функцию через другую функцию, где она все еще работает одинаково, но вместо этого ничего не печатается на стандартный вывод.Подавление вывода из функции печати в 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

Как просто добавить необязательный аргумент «print-output» to do-printing? –

+0

Мне нравится это решение для некоторых ситуаций, но оно не будет работать для моих нужд. Я писал основную единую тестовую структуру для myseltfjust, чтобы получить некоторую практику с языком, поэтому я не могу беспокоиться о том, чтобы добавить дополнительные аргументы для каждого потенциального печата. – Nyles

ответ

10

Простым решением является создание пустого потока .

(with-open-stream (*standard-output* (make-broadcast-stream)) 
    (call-some-function-1) 
    ... 
    (call-some-function-n)) 

Если в потоке вещания нет потока компонентов, все выходные данные будут отброшены. Выше связывается *standard-output* с таким потоком. Это не предотвращает никаких данных и переносится.

+0

Это изящное решение, спасибо. – Nyles

2

Вы можете просто перенаправить свой стандартный вывод в какое-то место. Например, в/dev/null, если у вас есть одна в вашей операционной системе. Это похоже на очень идиоматическое UNIX-выходное подавление.

Обратите внимание, что вы не должны устанавливать его в NIL, потому что в этом случае будет напечатана ошибка типа сигнала.

(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.

+0

Я использовал первый пример с выводом на строку, который вы дали, поскольку мне нужно только поставить это в одну функцию. Я все еще пытаюсь расшифровать все части, но сейчас это работает для моих нужд. Спасибо. – Nyles

Смежные вопросы