April 13, 2009
プログラミングGauche : 14章 入出力
14章 入出力
さすがに入出力は複雑だろうな、、、となんとなく身構えていたけれど、意外とすんなり頭に入った。すっきりと抽象化されていてわかりやすい。
最低限つかんでおくべきは、入力・出力のメソッド数種類と、ポートという考え方。後は必要に応じて参照すればいい。
まず、入力用メソッド。
これら入出力メソッドは、デフォルトでは標準入力(stdin)・標準出力(stdout)から読み書きを行う。
インタプリタから呼び出すと、↓のように動作する。
gosh> (read)
#\a
#\a
gosh> (read)
(1 2 3)
(1 2 3)
gosh> (print #\A " abc " '(1 2 3))
A abc (1 2 3)
#<undef>
入力元や出力先を抽象的に表現するのが、「ポート」。
ポートはディスプレイ、ファイル、文字列、ソケット、などに結び付けられていて、これを先の入出力メソッドに渡してやることで任意の入力元から入力/出力先へ出力することができる。
ポートを開くメソッドは、入出力の種類(ファイルか、文字列か、etc.)と入力用か出力用かの組み合わせで決まる。
$ cat foo.txt
'(a b c d)
gosh> (define in (open-input-file "foo.txt")) ; ポートを開く
in
gosh> (read in) ; ポートから読む
'(a b c d)
gosh> (close-input-port in) ; ポートを閉じる
#<undef>
gosh> (read in) ; 閉じたポートから読もうとするとエラー
*** IO-CLOSED-ERROR: I/O attempted on closed port: #<iport(closed) foo.txt 0x813f460>
基本的な使い方(出力)。
gosh> (define out (open-output-file "foo.txt")) ; ポートを開く
out
gosh> (write '(1 3 5) out) ; ポートへ書き込む
#<undef>
gosh> (close-output-port out) ; ポートを閉じる
#<undef>
gosh> (write #\a out) ; 閉じたポートへ書き込もうとするとエラー
*** IO-CLOSED-ERROR: I/O attempted on closed port: #<oport(closed) foo.txt 0x813f1c0>
$ cat foo.txt
(1 3 5)
基本は以上、あとはプログラミングをラクにするためのメソッドの紹介になる。
「ポートを開く→メソッド実行→ポートを閉じる」という一連の流れをまとめた(抽象化した)もの。
「標準入出力ポートを変更→メソッド実行」をまとめたもの。
さらに、
「ポートを開く→標準入出力を開いたポートへ変更→メソッド実行→ポートを閉じる」という至れり尽くせりのメソッドもあり。
ちょっと練習。
catコマンドもどき。
copyコマンドもどき。
プログラミングGauche
クチコミを見る
さすがに入出力は複雑だろうな、、、となんとなく身構えていたけれど、意外とすんなり頭に入った。すっきりと抽象化されていてわかりやすい。
最低限つかんでおくべきは、入力・出力のメソッド数種類と、ポートという考え方。後は必要に応じて参照すればいい。
まず、入力用メソッド。
- (read) : 入力からS式をひとつ読み込む。
- (read-char) : 入力から文字をひとつ読み込む。
- (read-line) : 入力から1行を読み込む。
- (read-byte) : 入力から1バイトを読み込む。
- (write <obj>) : オブジェクトの外部表現を出力する。
- (display <obj>) : オブジェクトを人が読みやすい形で出力する。
- (print [<obj> ...]) : (複数)オブジェクトを display 形式で出力する。
- (format <出力先> <書式> <引数> ...) : フォーマットして出力 (Cでいうprintfに近いもの)
これら入出力メソッドは、デフォルトでは標準入力(stdin)・標準出力(stdout)から読み書きを行う。
インタプリタから呼び出すと、↓のように動作する。
gosh> (read)
#\a
#\a
gosh> (read)
(1 2 3)
(1 2 3)
gosh> (print #\A " abc " '(1 2 3))
A abc (1 2 3)
#<undef>
入力元や出力先を抽象的に表現するのが、「ポート」。
ポートはディスプレイ、ファイル、文字列、ソケット、などに結び付けられていて、これを先の入出力メソッドに渡してやることで任意の入力元から入力/出力先へ出力することができる。
ポートを開くメソッドは、入出力の種類(ファイルか、文字列か、etc.)と入力用か出力用かの組み合わせで決まる。
- (open-input-file <ファイルのパス>)
- (open-output-file <ファイルのパス>)
- (get-input-string <文字列>)
- (get-output-string)
- (close-input-port <ポート>)
- (close-output-port <ポート>)
$ cat foo.txt
'(a b c d)
gosh> (define in (open-input-file "foo.txt")) ; ポートを開く
in
gosh> (read in) ; ポートから読む
'(a b c d)
gosh> (close-input-port in) ; ポートを閉じる
#<undef>
gosh> (read in) ; 閉じたポートから読もうとするとエラー
*** IO-CLOSED-ERROR: I/O attempted on closed port: #<iport(closed) foo.txt 0x813f460>
基本的な使い方(出力)。
gosh> (define out (open-output-file "foo.txt")) ; ポートを開く
out
gosh> (write '(1 3 5) out) ; ポートへ書き込む
#<undef>
gosh> (close-output-port out) ; ポートを閉じる
#<undef>
gosh> (write #\a out) ; 閉じたポートへ書き込もうとするとエラー
*** IO-CLOSED-ERROR: I/O attempted on closed port: #<oport(closed) foo.txt 0x813f1c0>
$ cat foo.txt
(1 3 5)
基本は以上、あとはプログラミングをラクにするためのメソッドの紹介になる。
「ポートを開く→メソッド実行→ポートを閉じる」という一連の流れをまとめた(抽象化した)もの。
- (call-with-input-file <file path> <1引数の手続き>)
- (call-with-output-file <file path> <1引数の手続き>)
- (call-with-input-string <string> <1引数の手続き>)
- (call-with-output-string <1引数の手続き>)
「標準入出力ポートを変更→メソッド実行」をまとめたもの。
- (with-input-from-port <入力ポート> <引数なしの手続き> <option> ...)
- (with-output-to-port <出力ポート> <引数なしの手続き> <option> ...)
- (with-error-to-port <エラーポート> <引数なしの手続き>)
- (with-ports <入力ポート> <出力ポート> <エラーポート> <引数なしの手続き>)
さらに、
「ポートを開く→標準入出力を開いたポートへ変更→メソッド実行→ポートを閉じる」という至れり尽くせりのメソッドもあり。
- (with-input-from-file <file path> <引数なしの手続き> <option> ...)
- (with-output-to-file <file path> <引数なしの手続き> <option> ...)
- (with-input-from-string <string> <引数なしの手続き>)
- (with-output-to-string <引数なしの手続き>)
ちょっと練習。
catコマンドもどき。
;; cat.scm
(define (cat . files)
(if (null? files)
#t
(call-with-input-file (car files)
(lambda (in)
(display (port->string in))
(apply cat (cdr files))))))
gosh> (cat "a.txt" "b.txt")
aaa
bbb
#t
copyコマンドもどき。
;; copy.scm
(define (copy src dst)
(call-with-input-file src
(lambda (in)
(with-output-to-file dst
(lambda ()
(display (port->string in)))))))
gosh> (copy "a.txt" "a_cp.txt")
#
gosh> (cat "a.txt")
aaa
#t
gosh> (cat "a_cp.txt")
aaa
#t
プログラミングGauche
クチコミを見る