Next: , Previous: , Up: Variables   [Contents][Index]


12.5 グローバル変数の定義

変数定義(variable definition)とは、そのシンボルをグローバル変数として使用する意図を表明する構文です。これには以下で説明するスペシャルフォームdefvardefconstが使用されます。

変数宣言は3つの目的をもちます。1番目はコードを読む人にたいして、そのシンボルが特定の方法(変数として)使用されることを意図したものだと知らせることです。2番目はLispシステムにたいしてオプションで初期値とドキュメント文字列を与えて、これを知らせることです。3番目はetagsのようなプログラミングツールにたいして、その変数が定義されている場所を見つけられるように情報を提供することです。

defconstdefvarの主な違いは、人間の読み手に値が変更されるかどうかを知らせることにあります。Emacs Lispは実際に、defconstで定義された変数の値の変更を妨げません。この2つのフォームの特筆すべき違いは、defconstは無条件で変数を初期化して、defvarは変数が元々voidのときだけ初期化することです。

カスタマイズ可能な変数を定義する場合は、defcustomを使用するべきです(これはサブルーチンとしてdefvarを呼び出す)。Variable Definitionsを参照してください。

Special Form: defvar symbol [value [doc-string]]

このスペシャルフォームは変数として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を参照のこと。

Special Form: defconst symbol value [doc-string]

このスペシャルフォームはある値で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を使用すると、これらのフォームはグローバルバインディングではなく、ローカルバインディングをセットします。これは通常は、あなたが望むことではないはずです。これを防ぐには、これらのスペシャルフォームをファイル内のトップレベルで使用します。この場所は通常、何のローカルバインディングも効果をもたないので、その変数にたいするローカルバインディングが作成される前にファイルがロードされることが確実だからです。