[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
印字(print)と読込み(read)は、Lispオブジェクトをテキス ト形式へ、またその逆に変換するための操作です。これらは、Lisp のデータ型で述べられている印字表現とリード構文を扱うものです。
この章では、読込みと印字のためのLisp関数について述べます。また、どこから テキストを得るか(読込みの場合)、あるいはどこへ出力するか(印字の場合)を指 定する、ストリーム(stream)についても述べます。
16.1 読込みと印字の概論 | ||
16.2 入力ストリーム | ||
16.3 入力関数 | テキストからLispオブジェクトを読み込むための関数。 | |
16.4 出力ストリーム | ||
16.5 出力関数 | Lispオブジェクトをテキストとして印字するための関数。 | |
16.6 出力に影響を与える変数 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispオブジェクトの読込み(read)とは、テキスト形式のLisp式を解析
して、対応するLispオブジェクトを生成することを意味します。これは、Lispプ
ログラムが、LispコードのファイルからLispの世界に入り込むための方法です。
このテキストを、そのオブジェクトのリード構文(read syntax)と呼びま
す。たとえばテキスト`(a . 5)'は、CARがa
でCDRが数
値5であるコンス・セルのリード構文です。
Lispオブジェクトの印字(print)とは、オブジェクトを表現するテキス トの生成、つまりオブジェクトからその印字表現への変換を意味します。上述の コンス・セルの印字では、`(a . 5)'というテキストが生成されます。
読込みと印字は、多かれ少なかれ逆の操作であるといえます。与えられた一片の
テキストの読込みによって生成されるオブジェクトの印字は、たいてい同じテキ
ストを生成し、あるオブジェクトの印字によって生成されるテキストの読込みは、
通常、同様なオブジェクトを生成します。たとえば、シンボルfoo
の印字
はテキスト`foo'を生成し、そのテキストの読込みはシンボルfoo
を
返します。要素がa
とb
であるリストの印字はテキスト`(a
b)'を生成し、そのテキストの読込みは、a
とb
を要素とするリス
ト(同じリストそのものではありませんが)を生成します。
しかしながら、厳密にはこれら二つの操作は逆ではありません。三種類の例外が あります:
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
テキスト読込み用のLisp関数のほとんどは、引数として入力ストリーム (input stream)を取ります。入力ストリームは、読み込むべきテキスト文字群 をどこから、あるいはどのように得るのかを指定するものです。入力ストリーム として使用可能な型には、以下のようなものがあります:
入力文字群は、バッファから読み込まれます。ポイント直後の文字から読 み始められます。ポイントは、読み込まれた文字数分だけ進みます。
入力文字群は、マーカがあるバッファから読み込まれます。そのマーカの 直後の文字から読み始められます。マーカの位置は、読み込まれた文字数分だけ 進みます。ストリームがマーカである場合、そのバッファのポイント値は何ら影 響を受けません。
入力文字群は、文字列から取られます。その文字列の先頭の文字から読み 始められ、必要なだけの文字が使われます。
入力文字群は、関数によって、その呼出しごとに一文字ずつ生成されます。 普通、その関数は、引数なしで呼び出されて一文字を返すものです。
時折、関数は、一つの引数(常に一文字)を以て呼び出されることがありま す。その場合、関数はその引数を保存し、次回の呼出しでそれを返すよう に準備します。これは、文字の読戻し(unread)と呼ばれます。Lispリー ダが一文字余分に読み込んでしまい、"それを読込み元へ戻したい"というとき に行なわれます。
t
ストリームとして用いられるt
は、入力がミニバッファから読み込まれる
ことを意味します。実際には、一度ミニバッファが呼び出され、そこでユーザに
よって与えられたテキストが、後で入力ストリームとして用いられる文字列へと
変換されます。
nil
入力ストリームとして与えられたnil
は、その代わりに変数
standard-input
の値を使用することを意味します。その値は、デフォ
ルト入力ストリーム(default input stream)であり、非nil
入力ストリー
ムでなくてはなりません。
入力ストリームとしてのシンボルは、そのシンボルの関数定義(もしあれば)と等 価です。
バッファ・ストリームからの読込みの例を、その前後でポイントがどこに位置す るかを記しながら、以下に示します:
---------- 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 ---------- |
最初の読込みでスペースをスキップしていることに注意してください。読込みは、 意味のあるテキストに先行するどんな量の空白もスキップします。
Emacs 18においては、シンボルの読込みは、そのシンボルを終結しているデリミ タを捨てていました。つまりポイントは、`the'の後ろではなく `contents'の先頭に位置したでしょう。Emacs 19の挙動は、あるオブジェ クトの終りとなる開括弧が別のオブジェクトの先頭として必要となる、 `bar(foo)'のような入力を正しく扱えるので、より優れています。
以下に、バッファの先頭に配置されたマーカ・ストリームからの読込みの例を示
します。readの値は、シンボル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
を返すでしょう。
この関数は、load
関数でオープンされた入力ファイルからの読込みを行
なう入力ストリームとして、内部的に使用されます。自分自身では、この関数を
使用しないでください。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この節では、読込みに関するLisp関数と変数について述べます。
以下の関数群において、streamは、入力ストリーム(前節参照)を表わして
います。streamがnil
であるか、あるいは省略された場合、変数
standard-input
の値がそのデフォルトとなります。
読込みが、終結されていないリスト、ベクタ、あるいは文字列に出会うと、
end-of-file
エラーが通知されます。
この関数は、streamからテキスト形式のLisp式を一つ読み込み、それを Lispオブジェクトとして返します。これは、基本的なLisp入力関数です。
この関数は、string内のテキストから最初のLisp式を読み込みます。そし て、CARがその式で、CDRがstring内の次の文字(まだ読み込ま れていない最初の文字)の位置を示す整数である、コンス・セルを返します。
startが与えられた場合、読込みは、string内の添字startの 位置から始められます(最初の文字が添字0)。また、endが与えられた場合、 読込みは、文字列の残りがなかったかのように、その添字の位置の直前で停止し ます。
例:
(read-from-string "(setq x 55) (setq y 5)") ⇒ ((setq x 55) . 11) (read-from-string "\"A short string\"") ⇒ ("A short string" . 16) ;; 最初の文字から読み始める。 (read-from-string "(list 112)" 0) ⇒ ((list 112) . 10) ;; 2番目の文字から読み始める。 (read-from-string "(list 112)" 1) ⇒ (list . 5) ;; 7番目の文字から読み始めて、 ;; 9番目で停止する。 (read-from-string "(list 112)" 6 8) ⇒ (11 . 8) |
この変数は、read
が、stream引数がnil
のときに用いる、
デフォルト入力ストリームを持っています。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
出力ストリームは、印字によって生成される文字で以て何をするのかを指定しま す。ほとんどの印字関数は、オプション引数として出力ストリームを受け付けま す。出力ストリームとして使用可能な型には、以下のようなものがあります:
出力文字群は、バッファのポイントへ挿入されます。ポイントは、挿入さ れた文字数分だけ進みます。
出力文字群は、マーカが指しているバッファの、そのマーカの位置へ挿入 されます。マーカの位置は、挿入された文字数分だけ進みます。ストリームがマー カである場合、そのバッファのポイント値は何ら影響を受けません。
出力文字群は、それらを別の場所へストアする責任をもつ関数に渡されま す。その関数は、引数として一文字を取り、出力されるべき文字数分の回数呼ば れます。受け取った文字で何をするかはまったく自由です。
t
出力文字群は、エコー領域に表示されます。
nil
出力ストリームとして指定されたnil
は、その代わりに変数
standard-output
の値を使用することを意味します。その値は、デ
フォルト出力ストリーム(default output stream)であり、非nil
出力ス
トリームでなくてはなりません。
出力ストリームとしてのシンボルは、そのシンボルの関数定義(もしあれば)と等 価です。
正当な出力ストリームの多くは、また入力ストリームとしても正当です。したがっ て入力と出力ストリームの違いは、主としてLispオブジェクトをどう使用するか の違いであり、オブジェクトの型の区別ではありません。
出力ストリームとして使用されるバッファの例を以下に示します。見てのとおり、 ポイントは最初、`the'の`h'の直前に位置しています。しかし最後に も、ポイントは同じ`h'の直前に位置しています。
---------- Buffer: foo ---------- This is t∗he contents of foo. ---------- Buffer: foo ---------- (print "This is the output" (get-buffer "foo")) ⇒ "This is the output" ---------- Buffer: foo ---------- This is t "This is the output" ∗he contents of foo. ---------- Buffer: foo ---------- |
では、出力ストリームとしてのマーカの使用を見てみます。マーカは最初、バッ
ファfoo
中の単語`the'の`t'と`h'の間にあります。そし
て最後には、そのマーカは、同じ`h'の前に位置し続けるよう、挿入された
テキストを跨いで進みました。いつものように示されたポイントの位置に注意し
てください。その影響を受けていません。
---------- Buffer: foo ---------- "This is the ∗output" ---------- Buffer: foo ---------- m ⇒ #<marker at 11 in foo> (print "More output for foo." m) ⇒ "More output for foo." ---------- Buffer: foo ---------- "This is t "More output for foo." he ∗output" ---------- Buffer: foo ---------- m ⇒ #<marker at 35 in foo> |
以下の例は、エコー領域への出力を示しています:
(print "Echo Area output" t) ⇒ "Echo Area output" ---------- Echo Area ---------- "Echo Area output" ---------- Echo Area ---------- |
最後に、出力ストリームとしての関数の使用を見てみます。関数
eat-output
は、与えられた各文字を取り、それをリスト
last-output
の先頭へconsします(see section コンス・セルとリストの生成)。そして最後
には、そのリストは出力されたすべての文字を含みますが、その内容は逆順になっ
ています。
(setq last-output nil) ⇒ nil (defun eat-output (c) (setq last-output (cons c last-output))) ⇒ eat-output (print "This is the output" 'eat-output) ⇒ "This is the output" last-output ⇒ (10 34 116 117 112 116 117 111 32 101 104 116 32 115 105 32 115 105 104 84 34 10) |
このリストを逆にすることによって、正しい順番で出力を出せるようになります:
(concat (nreverse last-output)) ⇒ " \"This is the output\" " |
concat
の呼出しは、リストを文字列へと変換するため、より明瞭にその
内容を見ることができます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この節では、Lispオブジェクトの印字に用いるLisp関数について述べます。
一部のEmacs印字関数は、その出力が正しく読み込まれ得るよう、必要に応じて 出力にquote文字を付加します。Quote文字は`"'と`\'です。これらは 文字列とシンボルとを区別し、また読込み時に文字列中の句読点文字がデリミタ として取られるのを防ぎます。完全な詳細については、See section 印字表現とリード構文。Quoteするかしないかの指定は、印字関数の選択によって行な います。
もし、そのテキストが再びLisp中に読み込まれるものであるなら、曖昧さを避け るため、quote文字をともなって印字するのが一番です。Lispプログラマのため に明確にLispオブジェクトを描写するのが目的なら、その場合も同様です。しか し、出力の目的が人間にとって見やすくすることであるなら、quoteなしで印字 するほうがよいでしょう。
自己参照型Lispオブジェクトの印字は、無限量のテキストを必要とします。場合 によっては、そのようなテキストの生成の試みは、スタック・オーバーフローを 引き起こします。Emacsはそのような再帰を検出し、すでに印字されているオブ ジェクトを再帰的に(訳注: 繰り返し)印字する代わりに、`#level' と印字します。たとえば以下での`#0'は、現在の印字操作のレベル0におけ るオブジェクトの再帰的参照を示しています:
(setq foo (list nil)) ⇒ (nil) (setcar foo foo) ⇒ (#0) |
以下の関数群において、streamは、出力ストリームを表わしています(出
力ストリームの解説については前節を参照)。streamがnil
である
か、あるいは省略された場合、変数standard-output
の値がそのデフォル
トとなります。
print
関数は、印字のための便利な手段です。これは、objectの前
の改行に加えて、後ろにも改行を付加しつつ、objectの印字表現を
streamへ出力します。Quote文字が用いられます。print
は
objectを返します。以下がその例です:
(progn (print 'The\ cat\ in) (print "the hat") (print " came back")) -| -| The\ cat\ in -| -| "the hat" -| -| " came back" -| ⇒ " came back" |
この関数は、objectの印字表現をstreamへ出力します。
print
のような出力を区切るための改行は印字しませんが、quote文字は
print
同様に用います。objectを返します。
(progn (prin1 'The\ cat\ in) (prin1 "the hat") (prin1 " came back")) -| The\ cat\ in"the hat"" came back" ⇒ " came back" |
この関数は、objectの印字表現をstreamへ出力します。 objectを返します。
この関数は、read
ではなく人間が読めるような出力を生成することを意
図しており、そのためquote文字は挿入せず、文字列の前後に二重引用符もつけ
ません。呼出しごとの字空けも行ないません。
(progn (princ 'The\ cat) (princ " in the \"hat\"")) -| The cat in the "hat" ⇒ " in the \"hat\"" |
この関数は、streamに改行を出力します。この名前は、"terminate print"を表わしています。
この関数は、characterをstreamに出力します。characterを 返します。
この関数は、prin1
に同じ引数を与えたときに印字されるテキストを内容
とする、文字列を返します。
(prin1-to-string 'foo) ⇒ "foo" (prin1-to-string (mark-marker)) ⇒ "#<marker at 2773 in strings.texi>" |
noescapeが非nil
の場合、出力におけるquote文字の使用が抑制さ
れます(この引数は、Emacsバージョン19以降でサポートされています)。
(prin1-to-string "foo") ⇒ "\"foo\"" (prin1-to-string "foo" t) ⇒ "foo" |
Lispオブジェクトの印字表現を文字列として得るための他の方法については、
文字と文字列間の変換のformat
を参照してください。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この変数の値は、印字関数が、stream引数がnil
のときに用いる、
デフォルト出力ストリームです。
この変数が非nil
の場合、文字列中の改行文字は`\n'として印字さ
れ、改ページ文字は`\f'として印字されます。普通、これらの文字は、実
際の改行、改ページとして印字されます。
この変数は、関数prin1
とprint
、またそれらを使用するすべてに
影響を与えます。princ
には影響を与えません。以下に、prin1
を
使用する例を示します:
(prin1 "a\nb") -| "a -| b" ⇒ "a b" (let ((print-escape-newlines t)) (prin1 "a\nb")) -| "a\nb" ⇒ "a b" |
二つ目の式において、prin1
の呼出しの間は
print-escape-newlines
の局所的な束縛が効いていますが、その結果の印
字のときには効いていません。
この変数の値は、印字されるリストの要素の最大数です。印字されるリストが、 これよりも多くの要素をもっている場合、省略符号(訳注: `...')によって短縮 されます。
この値がnil
の場合(デフォルト)、制限はありません。
(setq print-length 2) ⇒ 2 (print '(1 2 3 4 5)) -| (1 2 ...) ⇒ (1 2 ...) |
この変数の値は、丸括弧と角括弧が印字される際のネストの最大の深さです。こ
の制限を越える深さのリスト、あるいはベクタは、省略符号(訳注: `...')によっ
て短縮されます。nil
の値(デフォルト)は、制限しないことを意味します。
この変数は、バージョン19以降に存在します。
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Yasutaka SHINDOH on September, 29 2006 using texi2html 1.76.