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の値は変更されない。
たとえnil
であっても値を指定することにより、その変数は特別だと永続的にマークされることに注意。一方でvalueが省略されると変数はローカル(カレントのレキシカルスコープまたはトップレベルにあればファイル)でのみ特別だとマークされる。これはバイトコンパイルの警告を抑止するために有用。Compiler Errorsを参照のこと。
symbolがカレントバッファー内でバッファーローカルなバインディングをもつ場合、defvar
はデフォルト値に作用する。デフォルト値はバッファーローカルなバインディングではなく、バッファーにたいして独立である。デフォルト値がvoidのときはデフォルト値をセットする。Buffer-Local Variablesを参照のこと。
すでにsymbolがレキシカルにバインドされている場合(たとえばレキシカルバインドが有効な状態でlet
フォーム内にdefvar
があるような場合)、defvar
はダイナミックな値をセットする。バインディング構文を抜けるまで、レキシカルバインディングは効果をもつ。Variable Scopingを参照のこと。
Emacs LispモードでC-M-x
(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をリターンするが、これは通常は値が問題にならないファイル内のトップレベルで使用される。
値をもたないdefvar
のより詳細な使用例はLocal defvar exampleを参照のこと。
このスペシャルフォームはある値でsymbolを定義して、それを初期化する。これはコードを読む人に、symbolがここで設定される標準的なグローバル値をもち、ユーザーや他のプログラムがそれを変更すべきではないことを知らせる。symbolが評価されないことに注意。定義されるシンボルはdefconst
内に明示的に記されなければならない。
defvar
と同様、defconst
は変数を特別 —
この変数が常にダイナミックにバインドされているという意味 — であるとマークする(Variable Scopingを参照)。加えてこれはその変数を危険であるとマークする(File Local Variablesを参照)。
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
警告:
変数がローカルバインディングをもつとき(let
により作成された、または関数の引数の場合)に、スペシャルフォームdefconst
またはdefvar
を使用すると、これらのフォームはグローバルバインディングではなく、ローカルバインディングをセットします。これは通常は、あなたが望むことではないはずです。これを防ぐには、これらのスペシャルフォームをファイル内のトップレベルで使用します。この場所は通常、何のローカルバインディングも効果をもたないので、その変数にたいするローカルバインディングが作成される前にファイルがロードされることが確実だからです。