検索エンジンから来た人に注意このマニュアルは、Emacs ver. 19.x 向けのマニュアルを Mule 2.x の開発にあたり邦訳したものを、 電脳外道学会がミラーリングしているものであり、旧版製品パラノイアであるところの椅子人の趣味によるものです。しかしながら、現在の Emacs の主流は ver. 20 以降であり、ver 19.x と ver 20.x とでは、仕様の違いが少なからずあります。 したがって、一般的な Emacs ユーザーにとっては、
このマニュアルと実機の動作とが符合しない場合があります。
|
シーケンス(sequence)型は、リスト、ベクタ、文字列というほかの三つの Lisp型の和集合であることを思い出してください。いいかえれば、任意のリストは シーケンスであり、任意のベクタはシーケンスであり、任意の文字列は シーケンスです。全てのシーケンスが共通してもつ性質は、順序づけられた要素の 集まりだということです。
配列(array)は、プリミティブなオブジェクトの一つで、要素ごとに スロットを持ちます。全ての要素は、一定の時間でアクセス可能ですが、 既存の配列の長さを変えることはできません。文字列とベクタは配列の 二つの型です。
リストは要素の並びですが、プリミティブなオブジェクトの一つ ではありません。リストはコンス・セルからなり、要素ごとに一つのセルが 割当てられています。n番目の要素を見つけるには、n番目の コンス・セルまで全て見なければならないので、リストの先頭から遠い要素ほど アクセスに時間がかかります。しかし、リストだと要素を追加することや 取り除くことができます。
次の図式は、これらの型の間の関係を示しています:
ベクタとリストの要素は、任意のLispオブジェクトで構いません。 文字列の要素は、全て文字です。
Emacs Lispでは、シーケンス(sequence)は、リスト、ベクタ、 文字列のいずれかです。全てのシーケンスが共通してもつ性質は、 順序づけられた要素の集まりだということです。 本節では、これらのシーケンスを受けつける関数を説明します。
t
を、
そうでなければnil
を返します。
コピーに新たな要素を格納しても、元のsequenceに影響しませんし、
その逆も同じです。けれども、作られた方のシーケンスの要素はコピーでは
ありません。それらは元の要素と同一(eq
)のものです。
したがって、コピーされたシーケンスでこれらの要素内に行なった変更は、
元のシーケンスでも見ることができます。
もしそのシーケンスがテキスト属性をもつ文字列であるならば、 コピーでの属性リスト自身もコピーであり、元の属性リストを共有するものでは ありません。けれども、属性の実際の値は共有されています。 See section テキスト属性。
シーケンスをコピーするほかの方法については、
section コンス・セルとリストの生成のappend
、
section 文字列の生成のconcat
、
section ベクタのvconcat
なども参照してください。
(setq bar '(1 2)) => (1 2) (setq x (vector 'foo bar)) => [foo (1 2)] (setq y (copy-sequence x)) => [foo (1 2)] (eq x y) => nil (equal x y) => t (eq (elt x 1) (elt y 1)) => t ;; シーケンスの1要素を置き換える。 (aset x 0 'quux) x => [quux (1 2)] y => [foo (1 2)] ;; 共有要素の内部を修正する。 (setcar (aref x 1) 69) x => [quux (69 2)] y => [foo (69 2)]
sequence中の要素の個数を返します。sequenceがコンス・セルで
あっても、(最後のCDRがnil
ではないので)それがリストではないならば、
wrong-type-argument
エラーが通知されます。
(length '(1 2 3)) => 3 (length ()) => 0 (length "foobar") => 6 (length [1 2 3]) => 3
nil
を返します。それ以外の場合は、
args-out-of-range
エラーを発します。
(elt [1 2 3 4] 2) => 3 (elt '(1 2 3 4) 2) => 3 (char-to-string (elt "1234" 2)) => "3" (elt [1 2 3 4] 4) error-->Args out of range: [1 2 3 4], 4 (elt [1 2 3 4] -1) error-->Args out of range: [1 2 3 4], -1
この関数は、aref
(see section 配列に関する関数)と
nth
(see section リストの要素の参照)とを一般化したものです。
配列(array)オブジェクトは、スロットを持ち、そこにほかのLisp オブジェクトを複数、格納できます。それらを配列要素と呼びます。 任意の配列要素は一定の時間でアクセスできます。それに対しリストの要素は、 そのリスト内の位置に比例したアクセス時間を要します。
配列作成の際は、それがいくつ要素をもつかを指定しなければなりません。 割当てられる空間の大きさは要素数に依存します。したがって、いったん作成した 配列の大きさを変更することは不可能です。要素の追加や削除はできません。 しかし、要素を異なる値で置き換えることはできます。
Emacsは、ともに1次元である二つの配列型、文字列(string)と ベクタ(vector)を定義しています。ベクタは一般化された配列です。 つまり、その要素は任意のLispオブジェクトで構いません。文字列は、 その要素として文字(即ち、0から255までの整数)だけが許される、 特化した配列です。いずれの配列型も固有のリード構文を持ちます。 section 文字列型と、See section ベクタ型。
いずれの配列も次の特性を持ちます:
aref
やaset
で、それぞれ参照あるいは変更することが
できます(see section 配列に関する関数)。
原則的には、テキスト文字の配列が欲しい場合、文字列あるいはベクタの どちらでも構いません。しかし、実用的には、そのような場合は常に文字列を 選んでいます。それには四つ理由があります:
対照的に、(キー・シーケンスなどの)キーボード入力文字の配列に対しては、 ベクタであることが必要な場合もあります。というのも、多くの キーボード入力文字は、文字列に収まるような範囲の外にあるためです。 See section キー・シーケンス入力。
本節では、文字列とベクタを受けつける関数を説明します。
t
を返します。
(arrayp [a]) => t (arrayp "asdf") => t
(setq primes [2 3 5 7 11 13]) => [2 3 5 7 11 13] (aref primes 4) => 11 (elt primes 4) => 11 (aref "abcdefg" 1) => 98 ; `b' は ASCII コード 98.
section シーケンスにある関数elt
も参照してください。
(setq w [foo bar baz]) => [foo bar baz] (aset w 0 'fu) => fu w => [fu bar baz] (setq x "asdfasfd") => "asdfasfd" (aset x 3 ?Z) => 90 x => "asdZasfd"
arrayが文字列なのにobjectが文字ではないならば、
結果はwrong-type-argument
エラーとなります。
(setq a [a b c d e f g]) => [a b c d e f g] (fillarray a 0) => [0 0 0 0 0 0 0] a => [0 0 0 0 0 0 0] (setq s "When in the course") => "When in the course" (fillarray s ?-) => "------------------"
arrayが文字列なのにobjectが文字ではないならば、結果は
wrong-type-argument
エラーとなります。
シーケンス一般についての関数copy-sequence
やlength
は、
配列であろうオブジェクトに対してもしばしば有用です。
See section シーケンス。
Lispにおける配列は、ほとんどの言語における配列同様、メモリの ひとかたまりからなり、要素には一定の時間でアクセスできます。 ベクタ(vector)は汎用の配列であり、その要素は任意のLispオブェクトで 構いません(これに対して、Emacs Lispでのほかの配列文字列(string)では、 その要素は文字でなければなりません)。ベクタはEmacs内で、 構文テーブル(整数のベクタ)として、obarray(シンボルのベクタ)として、 キーマップ(コマンドのベクタ)として使われています。 内部的にはさらに、バイトコンパイルされた関数表現の一部としても使われます。 そのような関数を印字すると、ベクタが中にあるのが見えます。
Emacs Lispでは、ベクタ要素の添字は0からはじまり、そこから順に数えて 行きます。
ベクタは要素を角括弧で囲んだものとして表示されます。よって、要素が
シンボルa
, b
, a
であるベクタは、[a b a]
と
表示されます。Lispの入力でもベクタを同じように書くことができます。
ベクタは、文字列や数同様に、評価に際しては定数とみなされます。 その評価結果は同じベクタです。評価もされないし、ベクタの要素を調べることさえ されません。See section 自己評価型形式。
次に、これらの原則の例を示します。
(setq avector [1 two '(three) "four" [five]]) => [1 two (quote (three)) "four" [five]] (eval avector) => [1 two (quote (three)) "four" [five]] (eq avector (eval avector)) => t
ベクタに関係するいくつかの関数を挙げます:
t
を返します。
(vectorp [a]) => t (vectorp "asdf") => nil
(vector 'foo 23 [bar baz] "rats") => [foo 23 [bar baz] "rats"] (vector) => []
(setq sleepy (make-vector 9 'Z)) => [Z Z Z Z Z Z Z Z Z]
この値は新たに構築されたベクタであり、既存のいかなるベクタにもeq
では
ありません。
(setq a (vconcat '(A B C) '(D E F))) => [A B C D E F] (eq a (vconcat a)) => nil (vconcat) => [] (vconcat [A B C] "aa" '(foo (6 7))) => [A B C 97 97 foo (6 7)]
関数vconcat
もまた、引数として整数を許します。引数をその整数の
10進印字表現をなす数字文字列に変換し、それを元の整数の代わりに使用します。
この機能は削除する予定なので、使ってはなりません。すでにこの機能を
使っているならば、直ちにプログラムを変更してください!こういった方法で整数を
数字に変換したいならば、format
(see section 文字列の書式変換)
あるいはnumber-to-string
(see section 文字と文字列間の変換)を使ってください。
これ以外の結合用関数については、section マッピング関数にあるmapconcat
、
section 文字列の生成にあるconcat
、section コンス・セルとリストの生成にある
append
を参照してください。
append
関数でベクタを同じ要素をもつリストに変換する方法があります
(see section コンス・セルとリストの生成):
(setq avector [1 two (quote (three)) "four" [five]]) => [1 two (quote (three)) "four" [five]] (append avector nil) => (1 two (quote (three)) "four" [five])
Go to the first, previous, next, last section, table of contents.