proglog

主にプログラミングに関する断片的メモ

howm1日1ファイルの切り分け - その2

この続き。

ありがたいことに、コメントでアドバイスをして頂いた。
そして模範解答も。
もったいないので、整形した形でここに転記させて頂こうと思います。
shiroさん、ありがとうございます。

(use srfi-13)

(define (howmsplit file)
  (with-input-from-file file
    (lambda ()
      (let loop ((port #f)
		 (count 0))
	(let1 line (read-line)
	  (cond [(eof-object? line) (when port (close-output-port port))]
		[(string-prefix? "=" line)
		 (when port (close-output-port port))
		 (let1 port (open-output-file (x->string count))
		   (display line port) (newline port) (loop port (+ count 1)))]
		[else
		 (when port (display line port) (newline port))
		 (loop port count)]))))))

なんて言うか、自分がいかに迷宮に入っていたかがよく分かった。
手順をスッキリと表現できるんだなあ。

あと、僕のは、一緒に変化するもの(portとcount)とそれとは別に変化するもの(line)を一列に扱おうとして無理矢理なことになってたことか。

ちなみに、調べたらGaucheは()と[]を同じものとして扱うらしい。
Gauche 丸括弧も大括弧 [ ] も同様に扱われます - tigre
これは見やすいな。

whenはelse節なしのifか。
x->stringは、いわゆるtoString()メソッド的なものか。
let1は変数が一つの時のシンタックスシュガー的なGausheのマクロらしい。


学習のために、コメントを参考に、敢えてwith-output-to-fileを使ったケースを書き直してみる。

(use srfi-13)

(define (howmsplit)
  (with-input-from-file "./tut.howm"
    (lambda ()
      (let loop ((buf (read-line)) (filenum 0))
	(cond ((eof-object? buf) #t)
	      ((string-prefix? "=" buf)
	       (with-output-to-file (x->string filenum)
		 (lambda ()
		   (display buf)
		   (newline)
		   (let wloop ((buf (read-line)))
		     (cond ((eof-object? buf) #t)
			   ((string-prefix? "=" buf)
			    (loop buf (+ filenum 1)))
			   (else
			    (display buf)
			    (newline)
			    (wloop (read-line))))))))
	      (else (loop (read-line) filenum)))))))

こんな感じだろうか。
漸化式をそのままプログラムコード化するような感覚なのかな。

さて次ぎは、メモ日付からファイル名作成。