昨日の make-byte-string の項で出てきた #*”aaaaa” というのは不完全文字列(incomplete string)というものらしい。#*”…” というのが不完全文字列のリテラルね。
文字列について – Gauche – A Scheme Implementation から引用すると、
不完全文字列
全てのバイト列が可変長エンコーディングとして正しく解釈できるわけではない。 定義されていないコードポイントを指している場合はまだ可変長文字列として扱えるが、 そのエンコーディングではどうにも解釈しようの無いバイトシーケンスというのが 外部から入って来る可能性がある。
Gaucheではこのような文字列をincomplete stringと呼び、そのようにマークされる。 文字列操作系の関数は、incomplete stringを可能な限りあたかも1バイト固定長文字列のように扱う。 incomplete stringとcomplete stringが接合された場合、 結果はincomplete stringになる。
要するに、文字として解釈できない可能性のある文字列(バイト列)を不完全文字列と呼ぶようだ。
文字列が不完全文字列かどうかは string-incomplete? で判断できる。
gosh> (string-incomplete? "abc") #f gosh> (string-incomplete? #*"abc") #t
フツウの文字列 “abc” では #f が、不完全文字列 #*”abc” では #t が返ってきた。なるほど。
「外部から入って来る」というのは、例えばコマンドライン引数なんかだろうか。
(define main (lambda (args) (print (string-incomplete? (cadr args)))))
takatoh@nightschool $ gosh string-incomplete.scm foo #f
あれ、#f が返ってきた。てことは不完全文字列じゃないってことだ。
ファイルから入力した場合はどうだろう?
(define main (lambda (args) (print (string-incomplete? (call-with-input-file (cadr args) port->string)))))
takatoh@nightschool $ gosh string-incomplete2.scm input.txt #f
これも #f だ。
どういう時に不完全文字列になるんだろう?