Next: Tips for Defining, Previous: Void Variables, Up: Variables [Contents][Index]
変数定義(variable
definition)とは、そのシンボルをグローバル変数として使用する意図を表明する構成です。これには以下で説明するスペシャルフォームdefvarやdefconstが使用されます。
変数宣言は3つの目的をもちます。1番目は、コードを読む人にたいして、そのシンボルが特定の方法(変数として)使用されることを意図したものだと知らせることです。2番目は、Lispシステムにたいして、オプションで初期値とドキュメント文字列を与えて、これを知らせることです。3番目は、etagsのようなプログラミングツールにたいして、その変数が定義されている場所を見つけられるように、情報を提供することです。
defconstとdefvarの違いは主に、人間の読み手に、値が変更されるかどうかを知らせることにあります。Emacs
Lispは実際、defconstで定義された変数の値の変更を妨げません。この2つのフォームの特筆すべき違いは、defconstは無条件で変数を初期化し、defvarは変数が元々voidのときだけ初期化することです。
マスタマイズ可能な変数を定義する場合は、defcustomを使用するべきです(これはサブルーチンとしてdefvarを呼び出します)。Variable Definitionsを参照してください。
このスペシャルフォームは、変数としてsymbolを定義します。symbolは評価されないことに注意してください。シンボルはdefvarフォーム内に明示的に表記して定義される必要があります。この変数は特別だとマークされ、これは常にそれがダイナミックにバインドされることを意味します(Variable Scopingを参照してください)。
valueが指定されていてsymbolがvoid(たとえばこのシンボルがダイナミックにバインドされた値を持たないとき。Void Variablesを参照してください)、valueが評価されて、その結果がsymbolにセットされます。しかしsymbolがvoidでな場合、valueは評価されず、symbolの値は変更されません。valueが省略された場合、いかなる場合もsymbolの値は変更されません。
symbolがカレントバッファー内でバッファーローカルなバインディングをもつ場合、defvarはデフォルト値に作用します。デフォルト値はバッファーローカルなバインディングではなく、バッファーにたいして独立しています。デフォルト値がvoidのときはデフォルト値をセットします。Buffer-Local Variablesを参照してください。
すでにsymbolがレキシカルにバインドされている場合(たとえばレキシカルバインドが有効な状態でletフォーム内にdefvarがあるような場合)、defvarはダイナミックな値をセットします。バインディング構造を抜けるまで、レキシカルバインディングは効果をもちます。Variable Scopingを参照してください。
Emacs
Lispモード(eval-defun)でトップレベルのdefvarを評価するとき、eval-defunの特別な機能は、その値がvoidであるかテストすることなく、その変数を無条件にセットします。
引数doc-stringが与えられた場合、それは変数にたいするドキュメント文字列を指定します(そのシンボルのvariable-documentationプロパティーに格納されます)。Documentationを参照してください。
以下にいくつか例を示します。これはfooを定義しますが、初期化は行いません:
(defvar foo)
⇒ foo
この例はbarの値を23に初期化して、ドキュメント文字列を与えます:
(defvar bar 23
"The normal weight of a bar.")
⇒ bar
defvarフォームはsymbolをreturnしますが、通常これは値が問題にならないファイル内のトップレベルで使用されます。
このスペシャルフォームは、ある値としてsymbolを定義して、それを初期化します。これはコードを読む人に、symbolがここで設定される標準的なグローバル値をもち、ユーザーや他のプログラムがそれを変更すべきではないことを知らせます。symbolは評価されないことに注意してください。このシンボルは、defconst内に明示的に記されなければなりません。
defvarと同様、defconstは、変数を特別 —
この変数が常にダイナミックにバインドされているという意味 — だとマークします(Variable Scopingを参照してください)。加えて、これはその変数を危険であるとマークします(File Local Variablesを参照してください)。
defconstは常にvalueを評価して、その結果をsymbolの値にセットします。カレントバッファー内でsymbolがバッファーローカルなバインディングをもつ場合、defconstはデフォルト値ではなく、バッファーローカルな値をセットします(しかし、defconstで定義されたシンボルにたいしてバッファーローカルなバインディングを作るべきではありません)。
defconstの使い方の例は、Emacsのfloat-pi — (たとえIndiana State
Legislatureが何を試みようと)何者かにより変更されるべきではない、数学定数piにたいする定義です。しかし2番目のdefconstの例のように、これは単にアドバイス的なものです。
(defconst float-pi 3.141592653589793 "The value of Pi.")
⇒ float-pi
(setq float-pi 3)
⇒ float-pi
float-pi
⇒ 3
警告:
変数がローカルバインディングをもつとき(letにより作成された、または関数の引数の場合)に、スペシャルフォームdefconstまたはdefvarを使用すると、これらのフォームはグローバルバインディングではなく、ローカルバインディングをセットします。これは通常、あなたが望むことではないはずです。これを防ぐには、これらのスペシャルフォームをファイル内のトップレベルで使用します。この場所は通常、何のローカルバインディングも効果をもたないので、その変数にたいするローカルバインディングが作成される前にファイルがロードされることが確実だからです。