Next: Tips for Defining, Previous: Void Variables, Up: 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
を使うと、
ローカル束縛の値を変更し、グローバル束縛は変更しない。
これは望む効果ではない。
これを防ぐには、これらのスペシャルフォームはファイルのトップレベルで使う。
そうすれば、普通は有効なローカル束縛はない。
さらに、変数のローカル束縛を作るまえに、
確実にファイルをロードしておく。