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


11.6 Tips for Defining Variables Robustly

値が関数(または関数のリスト)であるような変数を定義するとき、変数の名前の最後に‘-function’(または‘-functions’)を使います。

他にも、変数名に関する慣習があります。以下はその完全なリストです:

…-hook

変数はノーマルフックです(Hooksを参照してください)。

…-function

値は関数です。

…-functions

値は関数のリストです。

…-form

値はフォーム(式)です。

…-forms

値はフォーム(式)のリストです。

…-predicate

値は述語(predicate) — 1つの引数をとる関数 — で、引数が“正しい(good)”"場合は非nil、“正しくない(bad)”場合はnilをreturnします。

…-flag

nilか、そうでないかだけが意味をもつような値です。そのような変数は結局、やがては多くの値をもつことが多いので、この慣習を強く推奨はしません。

…-program

値はプログラム名です。

…-command

値は完全なシェルコマンドです。

…-switches

値はコマンドにたいして指定するオプションです。

変数を定義するときは、その変数を“安全(safe)”とマークすべきか、それとも“危険(risky)”とマークすべきかを常に考慮してください。File Local Variablesを参照してください。

複雑な値を保持する変数(バインディングをもつkeymapなど)を定義、または初期化するとき、以下のように値の計算をすべてdefvarの中に配置するのが最良です:

(defvar my-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\C-c\C-a" 'my-command)
    …
    map)
  docstring)

この方法にはいくつかの利点があります。1つ目は、ファールをロード中にユーザーが中断した場合、変数はまだ初期化されていないか、初期化されているかのどちらかで、その中間ということはありません。まだ初期化されていない場合、ファイルをリロードすれば正しく初期化されます。2つ目は、1度初期化された変数は、ファイルをリロードしても変更されないことです。コンテンツの一部を変更(たとえばキーのリバインド)するフックをユーザーが実行した場合などに、これは重要です。3つ目は、C-M-xdefvarを評価すると、そのマップは完全に再初期化されることです。

defvarフォーム内に多すぎるコードを配置することには不利な点が1つあります。ドキュメント文字列が変数の名前から離れた場所に配置されることです。これを避ける安全な方法は以下の方法です:

(defvar my-mode-map nil
  docstring)
(unless my-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\C-c\C-a" 'my-command)
    …
    (setq my-mode-map map)))

これは初期化をdefvarの内側に配置した場合とまったく同じ利点をもちますが、変数を再度初期化したい場合は、各フォームにたいして1回ずつ、2度C-M-xをタイプしなければならない点が異なります。