次: Tips for Defining, 前: Void Variables, 上: Variables
スペシャルフォームdefconstやdefvarの変数定義を使って、
シンボルをグローバル変数として使う意図を表明できます。
Emacs Lispでは、定義には3つの目的があります。
まず、コードを読む人向けに、特定のシンボルを(変数として)特定目的に
使う意図があることを知らせます。
第2に、Lispシステムに対しては、値と説明文字列を提供して
これらのことを伝えます。
第3に、プログラム内の関数や変数のデータベースを作成する
etagsやmake-docfileなどのユーティリティに情報を提供します。
defconstとdefvarの違いは、主に好みの問題であり、
値が変更されるかどうかを人に伝えます。
Emacs Lispは、defconstやdefvarの宣言に基づいて
変数の使い方を制限することはしません。
しかしながら、初期化に関しては違いがあります。
defconstは無条件に変数を初期化しますが、
defvarは変数が空である場合にのみ初期化します。
このスペシャルフォームは、symbolを変数として定義し、 初期値や説明文字列を設定する。 この定義は、コードを読む人向けに、 値を設定したり変更する変数としてsymbolを使うことを伝える。 symbolは評価されないことに注意。 定義するシンボルは、
defvarに明示的に現れる必要がある。symbolの値が空でありvalueを指定してあると、
defvarはvalueを評価し、その結果をsymbolに設定する。 しかし、symbolにすでに値があれば(つまり、空でなければ)、 valueをまったく評価せず、symbolの値も変更しない。 valueを省略した場合、symbolの値をいっさい変更しない。symbolにカレントバッファでバッファローカルな束縛がある場合には、
defvarはデフォルト値に作用する。 それは、バッファには独立であり、現在の(バッファローカルな)束縛ではない。defvarは、デフォルト値が空の場合にデフォルト値を設定する。 see Buffer-Local Variables。emacs-lispモードにおいてC-M-x(
eval-defun)でトップレベルの フォームdefvarを評価すると、eval-defunの特別な機能により、 変数の値が空かどうかを調べずに無条件に変数に設定する。doc-stringがあれば、それは変数の説明文を指定する。 (説明文を指定できるのは、変数定義の主な利点の1つである。) 説明文はシンボルの属性
variable-documentationに格納する。 Emacsのヘルプ関数(see Documentation)は、この属性を調べる。doc-stringの最初の文字が`*'であると、 この変数をユーザーオプションと考えることを意味する。 これにより、ユーザーはコマンド
set-variableやedit-optionsを 使って簡単に変数を設定できる。 しかしながら、ユーザーオプションの変数には、defvarではなくdefcustomを使ったほうがよく、 そうすればカスタマイズ情報を指定できる。 see Customization。いくつか例をあげる。 つぎのフォームは
fooを定義するが初期化はしない。(defvar foo) => fooつぎの例は、
barの値を23に初期化し、説明文字列を与える。(defvar bar 23 "The normal weight of a bar.") => barつぎの例は、
barの説明文字列を変更し、 この変数をユーザーオプションにする。 しかし、barにはすでに値が設定してあるので、 その値は変更しない。 (さらに(1+ nil)は評価するとエラーになるが、 評価されないのでエラーはない。)(defvar bar (1+ nil) "*The normal weight of a bar.") => bar bar => 23つぎの例は、スペシャルフォーム
defvarに等価な式である。(defvar symbol value doc-string) == (progn (if (not (boundp 'symbol)) (setq symbol value)) (if 'doc-string (put 'symbol 'variable-documentation 'doc-string)) 'symbol)フォーム
defvarはsymbolを返すが、 通常このフォームはファイルのトップレベルで使われ、そこでは値は関係ない。
このスペシャルフォームは、symbolを変数として定義し初期化する。 この定義は、コードを読む人向けに、 symbolはこれ以降標準のグローバル値を持ち、 ユーザーや他のプログラムが変更すべきでないことを伝える。 symbolは評価されないことに注意。 定義するシンボルは、
defconstに明示的に現れる必要がある。
defconstは、valueがあればつねにvalueを評価し、 その結果をsymbolに設定する。 symbolにカレントバッファのバッファローカルな束縛がある場合には、defconstはデフォルト値を設定し、 バッファローカルな値にではない。 (しかし、defconstで定義するシンボルには、 バッファローカルな束縛を作るべきではない。)つぎの例では、
piは、(インディアナ州立法府はいうにおよばず) だれも変更すべきではないと考えられる定数である。 しかし、2番目のフォームからわかるように、これは単に助言でしかない。(defconst pi 3.1415 "Pi to five places.") => pi (setq pi 3) => pi pi => 3
この関数は、variableがユーザーオプション、つまり、 カスタマイズのためにユーザーが設定することを意図した変数であると、
tを返し、さもなければnilを返す。 (ユーザーオプション向け以外の変数は、Lispプログラムの内部目的用にあり、 それらについてユーザーが知る必要はない。)ユーザーオプション変数は、 属性
variable-documentationの最初の文字で他の変数と区別される。 その属性が存在して文字列であり、最初の文字が`*'であれば、 その変数はユーザーオプションである。
ユーザーオプション変数に属性variable-interactiveがあると、
コマンドset-variableはその属性値を使って、
変数の新しい値の読み取りを制御します。
この属性値は、interactiveの引数(see Using Interactive)
のように使われます。
しかしながら、この機能はdefcustom(see Customization)により
ほとんど廃れています。
警告:
変数にローカル束縛があるときに
スペシャルフォームdefconstやdefvarを使うと、
ローカル束縛の値を変更し、グローバル束縛は変更しない。
これは望む効果ではない。
これを防ぐには、これらのスペシャルフォームはファイルのトップレベルで使う。
そうすれば、普通は有効なローカル束縛はない。
さらに、変数のローカル束縛を作るまえに、
確実にファイルをロードしておく。