検索エンジンから来た人に注意このマニュアルは、Emacs ver. 19.x 向けのマニュアルを Mule 2.x の開発にあたり邦訳したものを、 電脳外道学会がミラーリングしているものであり、旧版製品パラノイアであるところの椅子人の趣味によるものです。しかしながら、現在の Emacs の主流は ver. 20 以降であり、ver 19.x と ver 20.x とでは、仕様の違いが少なからずあります。 したがって、一般的な Emacs ユーザーにとっては、
このマニュアルと実機の動作とが符合しない場合があります。
|
印字(print)と読込み(read)は、Lispオブジェクトをテキス ト形式へ、またその逆に変換するための操作です。これらは、section Lisp のデータ型で述べられている印字表現とリード構文を扱うものです。
この章では、読込みと印字のためのLisp関数について述べます。また、どこから テキストを得るか(読込みの場合)、あるいはどこへ出力するか(印字の場合)を指 定する、ストリーム(stream)についても述べます。
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を要素とするリス
ト(同じリストそのものではありませんが)を生成します。
しかしながら、厳密にはこれら二つの操作は逆ではありません。三種類の例外が あります:
テキスト読込み用のLisp関数のほとんどは、引数として入力ストリーム (input stream)を取ります。入力ストリームは、読み込むべきテキスト文字群 をどこから、あるいはどのように得るのかを指定するものです。入力ストリーム として使用可能な型には、以下のようなものがあります:
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関数でオープンされた入力ファイルからの読込みを行
なう入力ストリームとして、内部的に使用されます。自分自身では、この関数を
使用しないでください。
この節では、読込みに関するLisp関数と変数について述べます。
以下の関数群において、streamは、入力ストリーム(前節参照)を表わして
います。streamがnilであるか、あるいは省略された場合、変数
standard-inputの値がそのデフォルトとなります。
読込みが、終結されていないリスト、ベクタ、あるいは文字列に出会うと、
end-of-fileエラーが通知されます。
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のときに用いる、
デフォルト入力ストリームを持っています。
出力ストリームは、印字によって生成される文字で以て何をするのかを指定しま す。ほとんどの印字関数は、オプション引数として出力ストリームを受け付けま す。出力ストリームとして使用可能な型には、以下のようなものがあります:
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の呼出しは、リストを文字列へと変換するため、より明瞭にその
内容を見ることができます。
この節では、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"
printのような出力を区切るための改行は印字しませんが、quote文字は
print同様に用います。objectを返します。
(progn (prin1 'The\ cat\ in)
(prin1 "the hat")
(prin1 " came back"))
-| The\ cat\ in"the hat"" came back"
=> " came back"
この関数は、readではなく人間が読めるような出力を生成することを意
図しており、そのためquote文字は挿入せず、文字列の前後に二重引用符もつけ
ません。呼出しごとの字空けも行ないません。
(progn
(princ 'The\ cat)
(princ " in the \"hat\""))
-| The cat in the "hat"
=> " in the \"hat\""
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オブジェクトの印字表現を文字列として得るための他の方法については、
section 文字と文字列間の変換のformatを参照してください。
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以降に存在します。
Go to the first, previous, next, last section, table of contents.