Next: , Previous: , Up: Read and Print   [Contents][Index]


18.2 入力ストリーム

テキストを読み取るLisp関数の大部分は、引数として入力ストリーム(input stream)を受け取ります。入力ストリームは読み取られるテキストの文字をどこから、どのように取得するかを指定します。以下は利用できる入力ストリーム型です:

buffer

入力文字はbufferのポイントの後の文字から直接読み取られる。文字の読み取りとともにポイントが進む。

marker

入力文字はmarkerがあるバッファーの、マーカーの後の文字から直接読み取られる。文字の読み取りとともにマーカーが進む。ストリームがマーカーならバッファー内のポイント値に影響はない。

string

入力文字はstringの最初の文字から必要な文字数分が取得される。

function

入力文字はfunctionから生成され、その関数は2種類の呼び出しをサポートしなければならない:

t

tはその入力がミニバッファーから読み取られるストリームであることを意味する。実際にはミニバッファーが1回呼び出されて、ユーザーから与えられたテキストが、その後に入力ストリームとして使用される文字列となる。Emacsがbatchモードで実行されている場合には、ミニバッファーのかわりに標準入力が使用される。たとえば、

(message "%s" (read t))

このような場合には標準入力からLisp式が読み取られて、結果は標準出力にプリントされるだろう。

nil

入力ストリームとしてnilが与えられた場合は、かわりにstandard-inputの値が使用されることを意味する。この値はデフォルトの入力ストリーム(default input stream)であり、非nilの入力ストリームでなければならない。

symbol

入力ストリームとしてのシンボルは、(もしあれば)そのシンボルの関数定義と等価である。

以下の例ではバッファーストリームから読み込んで、読み取りの前後におけるポイント位置を示しています:

---------- Buffer: foo ----------
This∗ is the contents of foo.
---------- Buffer: foo ----------

(read (get-buffer "foo"))
     ⇒ is
(read (get-buffer "foo"))
     ⇒ the

---------- Buffer: foo ----------
This is the∗ contents of foo.
---------- Buffer: foo ----------

最初の読み取りではスペースがスキップされていることに注意してください。読み取りでは意味のあるテキストに先行する、任意のサイズの空白文字がスキップされます。

以下はマーカーストリームからの読み取りの例で、最初は表示されているバッファーの先頭にマーカーを配置されています。読み取られた値はシンボルThisです。


---------- Buffer: foo ----------
This is the contents of foo.
---------- Buffer: foo ----------

(setq m (set-marker (make-marker) 1 (get-buffer "foo")))
     ⇒ #<marker at 1 in foo>
(read m)
     ⇒ This
m
     ⇒ #<marker at 5 in foo>   ;; 最初のスペースの前

以下では文字列のコンテンツから読み取っています:

(read "(When in) the course")
     ⇒ (When in)

以下はミニバッファーから読み取る例です。プロンプトは‘Lisp expression: です(このプロンプトはストリームtから読み取る際は常に使用される)。ユーザーの入力はプロンプトの後に表示されます。

(read t)
     ⇒ 23
---------- Buffer: Minibuffer ----------
Lisp expression: 23 RET
---------- Buffer: Minibuffer ----------

最後はuseless-streamという名前の関数ストリームから読み取る例です。ストリームを使用する前に変数useless-listを文字のリストで初期化しています。その後はリスト内の次の文字を取得するため、または文字をリストの先頭に追加することにより読み戻すために関数useless-streamを呼び出します。

(setq useless-list (append "XY()" nil))
     ⇒ (88 89 40 41)

(defun useless-stream (&optional unread)
  (if unread
      (setq useless-list (cons unread useless-list))
    (prog1 (car useless-list)
           (setq useless-list (cdr useless-list)))))
     ⇒ useless-stream

このストリームを使って以下のように読み取ります:

(read 'useless-stream)
     ⇒ XY

useless-list
     ⇒ (40 41)

開カッコと閉カッコがリスト内に残されることに注意してください。Lispリーダーは開カッコに出会うと、それを入力の終わりと判断して読み戻します。次にこのポイント位置からこのストリームを読み取ると、‘()’が読み取られてnilがリターンされます。