@kyanny's blog

My thoughts, my life. Views/opinions are my own.

Common Lisp HyperSpec を眺める (4) write-string

Common Lisp HyperSpec のシンボルを眺めたり評価したりしています。今日は write-string です。

----------------------------------------------------------------------------------------------------------------------------------------------------------
Function WRITE-STRING, WRITE-LINE

Syntax:

write-string string &optional output-stream &key start end => string

write-line string &optional output-stream &key start end => string

Arguments and Values:

string---a string.

output-stream -- an output stream designator. The default is standard output.

start, end---bounding index designators of string. The defaults for start and end are 0 and nil, respectively.

Description:

write-string writes the characters of the subsequence of string bounded by start and end to output-stream. write-line does the same thing, but then
outputs a newline afterwards.

Examples:

 (prog1 (write-string "books" nil :end 4) (write-string "worms"))
>>  bookworms
=>  "books"
 (progn (write-char #\*)
        (write-line "test12" *standard-output* :end 5) 
        (write-line "*test2")
        (write-char #\*)
        nil)
>>  *test1
>>  *test2
>>  *
=>  NIL

Side Effects: None.

Affected By:

*standard-output*, *terminal-io*.

Exceptional Situations: None.

See Also:

read-line, write-char

Notes:

write-line and write-string return string, not the substring bounded by start and end.

 (write-string string)
==  (dotimes (i (length string)
      (write-char (char string i)))

 (write-line string)
==  (prog1 (write-string string) (terpri))

----------------------------------------------------------------------------------------------------------------------------------------------------------
The following X3J13 cleanup issues, not part of the specification, apply to this section:

  * RANGE-OF-START-AND-END-PARAMETERS:INTEGER-AND-INTEGER-NIL
  * SUBSEQ-OUT-OF-BOUNDS
   
----------------------------------------------------------------------------------------------------------------------------------------------------------

output-stream ってのはファイルハンドル的なものなのかな、まだ新しいストリームを開く方法がわからないので指定無しの場合のデフォルトである標準出力にしか出せませんが。

&key start end の指定部分がちょっと奇妙に見えます。 &key はそれに続く引数を、値を並べるんじゃなくて :end 4 みたいに名前と値のペアで渡すという約束なのかな。

文字列を書くだけなのであんまり面白い例が思い浮かびません。

CL-USER> (write-string "Hello, World!")
Hello, World!
"Hello, World!"
CL-USER> (write-string "Hello, World!" nil)
Hello, World!
"Hello, World!"
CL-USER> (write-string "Hello, World!" nil :start 0)
Hello, World!
"Hello, World!"
CL-USER> (write-string "Hello, World!" nil :start 1)
ello, World!
"Hello, World!"
CL-USER> (write-string "Hello, World!" nil :start 1 :end -1)
; Evaluation aborted.
CL-USER> (write-string "Hello, World!" nil :start 1 :end 10)
ello, Wor
"Hello, World!"
CL-USER> (write-string "Hello, World!" nil :start 1 :end 99)
; Evaluation aborted.
CL-USER> 

:end に負の数字や、文字列の長さよりも大きい数字を与えるとエラーになるようです。

*slime-repl sbcl* バッファで評価していますが、どうも標準出力に出てるものと返り値とが見た目で差がわからなくて混乱します。まぁ何度もやって慣れるしかないんだろうなぁ。