2010-01-16 14 views
11

Nie rozumiem dlaczego ten kod zachowuje się różnie w różnych implementacjach:Lisp format i siły wyjście

(format t "asdf") 
(setq var (read)) 

W clisp zachowuje się jak można by się spodziewać, z szybka wydrukowane następnie czytać, ale w SBCL odczytuje, , a następnie wyprowadza. Czytałem trochę w internecie i zmieniła go:

(format t "asdf") 
(force-output t) 
(setq var (read)) 

To również działa dobrze w clisp, ale w SBCL to nadal czyta, a potem wyjść. Próbowałem nawet oddzielić go na inną funkcję:

(defun output (string) 
    (format t string) 
    (force-output t)) 
(output "asdf") 
(setq var (read)) 

I nadal czyta, a potem wyjścia. Czy poprawnie używam force-output, czy jest to tylko idiosynkwalencja SBCL?

Odpowiedz

22

Należy użyć FINISH-OUTPUT.

W systemach ze zbuforowanymi strumieniami wyjściowymi, niektóre dane wyjściowe pozostają w buforze wyjściowym, dopóki bufor wyjściowy nie zostanie zapełniony (następnie zostanie automatycznie zapisany w miejscu docelowym) lub bufor wyjściowy zostanie explicity opróżniony.

Common Lisp ma trzy funkcje, które:

  • FINISH-OUTPUT, usiłuje zapewnić, że cała produkcja odbywa się, a następnie wraca.

  • , uruchamia pozostałe wyjście, ale NATYCHMIAST zwraca i NIE czeka na wszystkie wykonane dane.

  • CLEAR-OUTPUT, próbuje usunąć wszystkie oczekujące dane wyjściowe.

Również T w FORCE-OUTPUT i FORMAT niestety nie są takie same.

  • force-output/finish-output: T jest *terminal-io* i NIL jest *standard-output*

  • FORMAT: T jest *standard-output*

to powinno działać:

(format t "asdf") 
(finish-output nil) ; note the NIL 
(setq var (read)) 
+0

dzięki, to działało! –

+0

Inną opcją, jak w [Practical Common Lisp] (http://www.gigamonkeys.com/book/practical-a-simple-database.html), jest użycie globalnego '* query-io *' zamiast t lub zero. – lindes