Next: , Previous: , Up: 変数   [Contents][Index]


12.5 グローバル変数の定義

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

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

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

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

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

このスペシャルフォームは変数としてsymbolを定義する。symbolが評価されないことに注意。シンボルはdefvarフォーム内に明示的に表記して定義される必要がある。この変数は特別だとマークされて、これは常に変数がダイナミックにバインドされることを意味する(変数のバインディングのスコーピングルールを参照)。

valueが指定されていてsymbolがvoid(たとえばこのシンボルがダイナミックにバインドされた値を持たないとき。変数がvoidのときを参照)ならvalueが評価されて、その結果がsymbolにセットされる。しかしsymbolがvoidでなければ、valueは評価されずsymbolの値は変更されない。valueが省略された場合は、いかなる場合もsymbolの値は変更されない。

たとえnilであっても値を指定することにより、その変数は特別だと永続的にマークされることに注意。一方でvalueが省略されると変数はローカル(カレントのレキシカルスコープまたはトップレベルにあればファイル)でのみ特別だとマークされる。これはバイトコンパイルの警告を抑止するために有用。コンパイラーのエラーを参照のこと。

symbolがカレントバッファー内でバッファーローカルなバインディングをもつ場合、defvarはデフォルト値に作用する。デフォルト値はバッファーローカルなバインディングではなく、バッファーにたいして独立である。デフォルト値がvoidのときはデフォルト値をセットする。バッファーローカル変数を参照のこと。

すでにsymbolがレキシカルにバインドされている(レキシカルバインディングが有効な状態でletフォーム内にdefvarがある)場合には、defvarはダイナミックな値をセットする。レキシカルバインディングはそのバインディング構文を抜けるまで効果し続ける。変数のバインディングのスコーピングルールを参照のこと。

C-M-x (eval-defun)、またはEmacs LispモードでC-x C-e (eval-last-sexp)によりトップレベルのdefvarを評価する際には、これら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のより詳細な使用例はLocal defvar exampleを参照のこと。

Special Form: defconst symbol value [doc-string]

このスペシャルフォームはある値でsymbolを定義して、それを初期化する。これはコードを読む人に、symbolがここで設定される標準的なグローバル値をもち、ユーザーや他のプログラムがそれを変更すべきではないことを知らせる。symbolが評価されないことに注意。定義されるシンボルはdefconst内に明示的に記されなければならない。

defvarと同様、defconstは変数を特別 — この変数が常にダイナミックにバインドされているという意味 — であるとマークする(変数のバインディングのスコーピングルールを参照)。加えてこれはその変数を危険であるとマークする(ファイルローカル変数を参照)。

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