2012年4月24日火曜日

Scheme第6歩


I/Oの話。
まずはポート(port)について。他の言語ではファイルハンドルとかストリームとか呼ばれているものを、Schemeではポートと呼ぶ。ポートの扱いは他の言語のファイルと同様、オープン→読み/書き→クローズという流れ。

入力ファイルのオープンは
(open-input-file "filename")
出力ファイルのオープンは
(open-output-file "filename")
で行う。これらは第2引数以降に細かいオプションを指定可能。

文字列をポートとして扱うことも可能。
(open-input-string "string")
で取得した入力ポートからは、第1引数に指定した文字列が読みだされる。また
(open-output-string)
で取得した出力ポートに書き込んだデータは、
(get-output-string)
で文字列として取得することができる。なお、get-output-stringは副作用がない。

読み書きの前にクローズ。入力ポートiのクローズは
(close-input-port i)
出力ポートoのクローズは
(close-output-port o)
とする。

さて、いよいよ読み書き。まずは主だったプロシージャを列挙する。
read-char i入力ポートiから1文字読み込み
read-line i入力ポートiから1行読み込み
read-byte i入力ポートiから1バイト読み込み
read-block n i入力ポートiからnバイト読み込み
read i入力ポートiからフォームを1つ読み込み
write-char c o出力ポートoへ文字cを書き出し
write-byte b o出力ポートoへバイトデータbを書き出し
write f o出力ポートoへフォームfを書き出し
display f o出力ポートoへフォームfを人間が読みやすい形で書き出し
newline o出力ポートoへ改行文字を書き出し
いずれも、入力ポートの指定を省略すれば標準入力(standard-input-port)が、出力ポートの指定を省略すれば標準出力(standard-output-port)が使用される。ついでに、標準エラー出力は(standard-error-port)。

write, readについて補足。writeはフォームをSchemeの処理系が解釈できる形の文字列にして書き込む。readはその逆で、処理系が解釈できるようなフォームの文字列表現を読み出す。

ポートのクローズの面倒を見てくれる、Rubyでいうブロック付きIO.openのようなものがSchemeにもある。
(call-with-input-file "filename" (lambda (i) ...))
(call-with-input-string "string" (lambda (i) ...))
(call-with-output-file "filename" (lambda (o) ...))
(call-with-output-string "string" (lambda (o) ...))
いずれも第1引数に従ってポートをオープンし、そのポートを引数とする第2引数のプロシージャを呼び出した後、ポートをクローズする。

0 件のコメント:

コメントを投稿