Previous: , Up: Variable Scoping   [Contents][Index]


11.9.4 Using Lexical Binding

Emacs Lispファイルをロードしたり、Lispバッファーを評価するとき、バッファーローカルな変数lexical-bindingが非nilの場合は、レキシカルバインディングが有効になります:

Variable: lexical-binding

このバッファーローカルな変数が非nilの場合、Emacs Lispファイルおよびバッファーは、ダイナミックバインディングではなくレキシカルバインディングを使用して評価されます(しかし、特別な変数はダイナミックにバインドされたままです。以下を参照してください)。nilの場合、すべてのローカル変数にたいしてダイナミックバインディングが使用されます。この変数は通常、ファイルローカル変数として、Emacs Lispファイル全体にたいしてセットされます(File Local Variablesを参照してください)。他のファイルローカル変数などとは異なり、ファイルの最初の行でセットされなければならないことに注意してください。

eval呼び出しを使用して、Emacs Lispコードを直接評価するとき、evallexical引数が非nilの場合は、レキシカルバインディングが有効になります。Evalを参照してください。

レキシカルバインディングが有効な場合でも、特定の変数はダイナミックにバインドされたままです。これらはスペシャル変数(special variable)と呼ばれます。defvardefcustomdefconstで定義されたすべての変数は、スペシャル変数です(Defining Variablesを参照してください)。その他のすべての変数はレキシカルバインディングの対象になります。

Function: special-variable-p symbol

この関数は、symbolがスペシャル変数(つまり変数がdefvardefcustomdefconstによる定義をもつ)の場合は非nilをreturnします。それ以外では、return値はnilになります。

関数内での通常の引数としてスペシャル変数を使用することは、推奨されません。レキシカルバインディングモードが有効なときにこれを行うと、不定な動作が起こります(あるときはレキシカルバインディング、またあるときはダイナミックバインディングのように)。

Emacs Lispプログラムをレキシカルバインディングに変換するのは簡単です。最初にEmacs Lispソースファイルのヘッダー行でlexical-bindingtして、ファイルローカル変数を追加します(File Local Variablesを参照してください)。次に、意図せずレキシカルにバインドしてしまわないように、ダイナミックなバインドをもつ必要がある変数が変数定義をもつことを、各変数ごとにチェックします。

どの変数が変数定義をもつ必要があるか見つけるシンプルな方法は、ソースファイルをバイトコンパイルすることです。Byte Compilationを参照してください。letフォームの外で非スペシャル変数が使用されている場合、バイトコンパイラーは“free variable”にたいする参照または割り当てについて警告するでしょう。非スペシャル変数がバインドされているが、letフォーム内で使用されていない場合、バイトコンパイラーは“unused lexical variable”に関して警告するでしょう。バイトコンパイラーは、スペシャル変数を関数の引数として使用している場合も、問題を警告します。

(使用されていない変数についての警告を抑制するためには、単に変数名をアンダースコアーで開始します。そうすれば、バイトコンパイラーはこれを、変数が使用されないことを示すと解釈します。)