with-open-fileマクロ
ファイルを扱う際には、openやcloseを隠蔽している、with-open-fileマクロというのを使うのが主流のようだ。マクロは、macroexpand関数で展開できるらしい。試しにwith-open-fileを展開してみると、
? (macroexpand '(with-open-file (stream path :direction :input))) (LET (#:G19 #:G20) (UNWIND-PROTECT (MULTIPLE-VALUE-PROG1 (LET ((STREAM (SETQ #:G19 (OPEN PATH :DIRECTION :INPUT))))) (SETQ #:G20 T)) (WHEN #:G19 (CLOSE #:G19 :ABORT (NULL #:G20))))) T ?
となった。・・・よくわからないのが出てきたぞ・・・unwind-protectとか、mutiple-value-prog1とか・・・
こいつらはおいおい調べていこう。
実際にwith-open-fileを使ってみる。昨日の例だと、複数行あるテキストも1行しか出力しなかったので、EOFまで出力するようなサンプルを作成。こんな感じになった。
(defun cat (path) (with-open-file (stream path :direction :input) (loop (let ((line (read-line stream nil 'eof))) (if (eql line 'eof) (return)) (format t "~A~%" line)))))
unwind-protectは、Javaでいうところのtry/catch/finallyに似ている概念かもしれない。絶対にクローズさせるようになっているのかも。