変数定義とは、シンボルをグローバル変数として使用する意図を示す構文です。これには、以下に説明する特殊形式
defvar または defconst
が用いられます。
変数定義には3つの目的があります。第一に、コードを読む人に対し、そのシンボルが(変数として)特定の方法で使用される意図されていることを伝えます。第二に、Lispシステムにこの情報を伝え、必要に応じて初期値とドキュメント文字列を提供します。第三に、etagsなどのプログラミングツールに情報を提供し、変数がどこで定義されたかを特定できるようにします。
defconst と defvar
の違いは主に意図によるもので、値が変化する可能性があるかどうかを人間の読者に知らせるためのものです。Emacs Lisp では、defconst
で定義された変数の値を変更することを実際に制限しているわけではありません。これら2つの形式の顕著な違いの一つは、defconst が無条件に変数を初期化するのに対し、defvar は元から void である場合にのみ初期化を行う点です。
カスタマイズ可能な変数を定義するには、defcustom(defvarをサブルーチンとして呼び出す)を使用してください。カスタマイズ変数の定義を参照してください。
この特殊な形式では、symbol
を変数として定義し、必要に応じて初期化およびドキュメント化を行います。なお、symbol
は評価されません。定義対象のシンボルは、defvar
の形式で明示的に記述する必要があります。また、defvar は symbol を 特殊
としてマークします。これは、その束縛が常に動的である必要があることを意味します(変数束縛のスコープ規則 を参照してください)。
value が指定されており、かつ symbol が
void(すなわち、動的に束縛された値を持たない。変数が
void の場合 を参照)である場合、defvar は value を評価し、その評価結果を代入することで symbol
を初期化します。しかし、symbol が void でない場合、defvar は value を評価せず、symbol の値は変更されません。value
が省略されている場合、defvar はいかなる場合でも symbol の値を変更しません。
なお、nil
であっても値を指定すると、その変数は恒久的に特殊変数としてマークされる点に注意してください。一方、value を省略した場合、defvar
はその変数を局所的にのみ(すなわち、現在の字句スコープ内、あるいは defvar
がトップレベルにある場合は現在のファイル内)特殊変数としてマークします。これは、バイトコンパイルの警告を抑制する際に有用です。詳細は コンパイラエラー を参照してください。
現在のバッファにおいて symbol がバッファローカルな束縛を持ち、かつ value が指定されている場合、defvar
はバッファローカルな束縛ではなく、バッファに依存しない symbol
のデフォルト値を変更します。デフォルト値が void である場合は、その値を設定します。バッファローカル変数 を参照してください。
symbol がすでに let 束縛されている場合(例:defvar 形式が let
形式内に現れる場合)、defvar は set-default-toplevel-value と同様に symbol のトップレベルデフォルト値を設定します。let 束縛は、その束縛構文を抜けるまで有効です。変数束縛のスコープ規則 を参照してください。
Emacs Lispモードで、トップレベルの defvar フォームを C-M-x (eval-defun) または C-x C-e (eval-last-sexp)
で評価すると、これら2つのコマンドの特殊な機能により、変数の値が void であるかどうかの判定を行うことなく、無条件に変数が設定されます。
doc-string 引数が指定された場合、変数のドキュメント文字列(シンボルの variable-documentation プロパティに格納される)が指定されます。ドキュメントを参照してください。
以下にいくつか例を挙げます。このフォームでは foo を定義していますが、初期化は行っていません:
(defvar foo)
⇒ foo
この例では、bar の値を 23
に初期化し、ドキュメント文字列を付与しています:
(defvar bar 23
"The normal weight of a bar.")
⇒ bar
defvar 形式は symbol
を返しますが、通常は値が重要ではないファイルのトップレベルで使用されます。
値を指定せずに defvar を使用するより詳細な例については、ローカル defvar
の例を参照してください。
この特殊形式は、symbol を値として定義し、初期化します。これにより、コードの読者は、symbol
がここで設定された標準的なグローバル値を持ち、ユーザーや他のプログラムによって変更されるべきではないことを理解できます。なお、symbol は評価されません。定義対象のシンボルは、defconst に明示的に記述されている必要があります。
defconst 形式は、defvar
と同様に、その変数を特殊としてマークします。つまり、常に動的にバインドされるべきであることを意味します(変数バインドのスコープ規則を参照)。さらに、この形式は変数をリスクのあるものとしてマークします(ファイルローカル変数を参照)。
defconst は常に value
を評価し、その結果を symbol の値に設定します。symbol が現在のバッファでバッファローカルなバインディングを持っている場合、defconst はバッファローカルな値ではなくデフォルト値を設定します。(ただし、defconst で定義されたシンボルに対してバッファローカルなバインディングを作成すべきではありません。)
defconst の使用例としては、Emacs による float-pi の定義――数学定数 pi
であり、(インディアナ州議会による試みはあったものの)誰も変更すべきではないもの――が挙げられます。しかし、2番目の形式が示す通り、defconst はあくまで推奨に留まるものです。
(defconst float-pi 3.141592653589793 "The value of Pi.")
⇒ float-pi
(setq float-pi 3)
⇒ float-pi
float-pi
⇒ 3