2011-12-25 2 views
1

Я пишу хронометр в общем lisp, вывод отображается в стандартном выводе. то, что я пытаюсь сделать, это заменить выход без печати новой строки и без печати бок о бок, но переписывая предыдущий вывод, поэтому существует иллюзия непрерывности.замена/перезапись стандартного вывода в lisp

есть ли вообще, чтобы сделать это в общем lisp?

+1

что стандартный вывод будет? Файл? Сетевое соединение? Терминал? Какой терминал? –

ответ

3

ОК, прочитав комментарии, я лучше понимаю ваши намерения. Из вашего первоначального вопроса я предположил, что вы хотите заменить/увеличить результат какого-либо другого кода. Но теперь я понимаю, что вы на самом деле хотите, чтобы обновил экран. Это невозможно сделать с помощью однопоточного ввода-вывода, вам нужна другая библиотека IO, такая как ncurses.

Общая привязка Lisp для ncurses - это cl-charms системы (доступно в QuickLisp). Нет специальной документации cl-charms, но документация по использованию ncurses в C может применяться практически без изменений. Вот простая реализация для задачи, которую вы описываете, т.е. он показывает (в течение 10 секунд) часы в левом верхнем углу экрана:

(defun clock() 
    (charms:initscr) 
    (charms:clear) 
    (charms:curs-set 0) 
    (loop with start = (get-universal-time) 
     do (multiple-value-bind (s m h) (get-decoded-time) 
      (charms:mvaddstr 0 0 (format nil "~2,'0d:~2,'0d:~2,'0d" h m s))) 
      (charms:refresh) 
     until (>= (- (get-universal-time) start) 10)) 
    (charms:endwin)) 

Две проблемы, я испытал с этим:

  • Это работал только в терминале, а не в буфер Emacs slime-repl.

  • cl-charms не удалось найти мою установку библиотеки curses самостоятельно. Он искал библиотеку с именем «libcurses.so» или «libncurses.so», но в моей системе библиотека присутствовала только с версиями имен. Поэтому мне пришлось использовать перезапуск USE-VALUE во время загрузки библиотеки и предоставить альтернативное значение ("libncurses.so.5") для списка имен библиотек. Для частого использования библиотеки вы, вероятно, захотите изменить исходный код библиотеки и, возможно, предложить заплату разработчикам.

КН-амулеты домашняя страница связана с CLiki не доступен, но хранилище на http://gitorious.org/cl-charms есть.

Вот краткое описание функций Ncurses/CL-шармы, которые я использовал в примере:

  • initscr инициализирует Ncurses.
  • clear очищает экран.
  • curs-set устанавливает видимость курсора, 0 означает невидимость.
  • mvaddstr перемещает курсор в координаты y, x и записывает там строку, заменяя то, что было на экране ранее.
  • refresh делает изменения на экране фактически видимыми.
  • endwin - это функция очистки для вызова, когда вы закончите с ncurses.

Если я правильно понял, что вы пытаетесь сделать, лучший подход, как представляется, создать класс потока нового выхода (то есть подкласс fundamental-character-output-stream, предполагая, что ваше осуществление поддерживает Грея Streams) ,Вероятно, вы должны предоставить методы, специализированные для вашего класса, по крайней мере, для stream-write-char и stream-write-string.

Затем можно обернуть код с переопределением *standard-output* к экземпляру вашего класса, примерно так:

(let ((*standard-output* (make-instance 'your-stream-class 
             :target *standard-output*))) 
    (function-to-be-called-with-wrapped-standard-output)) 

+0

Я совсем не знаком с классами Lisp, никогда не использовал CLOS и фокусировался только на функциональном подходе. есть ли какой-либо ресурс, который я могу найти, чтобы получить разъяснения по вашему подходу? – momo

+0

Если бы вы были более конкретными в описании того, что вы хотите сделать, у меня может возникнуть некоторое представление о том, как это сделать без CLOS. Но если вы хотите попробовать этот подход, вам обязательно нужно узнать о CLOS, например, в главах 16 и 17 Практического Общего Лиспа (http://www.gigamonkeys.com/book/). После этого вы можете ознакомиться с документацией по реализации Gray Streams. –

+0

, поэтому я пытаюсь заставить хронометр отображать что-то вроде этого: 0: часы 0: минуты 11 секунд. затем переходите к отображению 0: часов 0: минут 12 секунд и т. д., но на том же пространстве предыдущего дисплея, а не на другой строке или рядом друг с другом и т. д. Я сделал это в python, когда писал симулятор жизни, вызывая четкий экран в bash после каждого прохода конструкции цикла. – momo

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