各シンボルは4つの構成要素(もしくは“セル”)をもち、構成要素はそれぞれ別のオブジェクトを参照します:
そのシンボルの名前。
変数としてのそのシンボルの現在値。
そのシンボルの関数定義。シンボル、キーマップ、キーボードマクロも保持できる。
そのシンボルのプロパティリスト。
プリント名のセルは常に文字列を保持し、それを変更することはできません。他の3つのセルには、任意のLispオブジェクトをセットすることができます。
プリント名のセルはシンボルの名前となる文字列を保持します。シンボルはシンボル名によりテキストとして表されるので、2つのシンボルが同じ名前をもたないことが重要です。Lispリーダーはシンボルを読み取るごとに、それを新規作成する前に、指定されたシンボルがすでに存在するかを調べます。シンボルの名前を得るには関数symbol-name
(シンボルの作成とinternを参照)を使用します。しかしシンボルがそれぞれ一意なプリント名(print
name)を1つだけもつとしても、“ショートハンド(shorthand)”と呼ばれる違うエイリアス名を通じて同じシンボルを参照することは可能です(ショートハンドを参照)。
値セルは変数としてのシンボルの値(そのシンボル自身がLisp式として評価されたときに得る値)を保持します。ローカルバインディング(local
binding)やスコーピングルール(scoping
rules)等のような複雑なものを含めて、変数のセットや取得方法については変数を参照してください。ほとんどのシンボルは値として任意のLispオブジェクトをもつことができますが、一部の特別なシンボルは変更できない値をもちます。これらにはnil
、t
、および名前が‘:’で始まるすべてのシンボル(キーワード(keyword)と呼ばれる)が含まれます。変更不可な変数を参照してください。
関数セルはシンボルの関数定義を保持します。実際はにはfoo
の関数セルの中に保管されている関数を意味するときに、“関数foo
”といってそれを参照することがよくあります。わたしたちは必要なときだけ、これを明確に区別することにします。関数セルは通常は関数(関数を参照)か、マクロ(マクロを参照)を保持するために使用されます。しかし関数セルはシンボル(シンボル関数インダイレクションを参照)、キーボードマクロ(キーボードマクロを参照)、キーマップ(キーマップを参照)、またはオートロードオブジェクト(自動ロードを参照)を保持するためにも使用できます。シンボルの関数セルの内容を得るには、関数symbol-function
(関数セルの内容へのアクセスを参照)を使用します。
プロパティリストのセルは、通常は正しくフォーマットされたプロパティリストを保持するべきです。シンボルのプロパティリストを得るには関数symbol-plist
を使用します。シンボルのプロパティを参照してください。
値セルがvoid(空)のときもあります。voidとはそのセルがどのオブジェクトも参照していないことを意味します(これはシンボルvoid
を保持するのともシンボルnil
を保持するのとも異なる)。voidの値セルを調べようとすると結果は‘Symbol's
value as variable is void’のようなエラーとなります。
各シンボルは値セルと関数セルを別個にもつので、変数名と関数名が衝突することはありません。たとえばシンボルbuffer-file-name
が値(カレントバッファーでvisitされているファイルの名前)をもつと同様に、関数定義(ファイルの名前をリターンするプリミティブ関数)をもつことができます:
buffer-file-name ⇒ "/gnu/elisp/symbols-ja.texi" (symbol-function 'buffer-file-name) ⇒ #<subr buffer-file-name>