検索エンジンから来た人に注意このマニュアルは、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.