Emacs Lispプログラムをレキシカルバインディングに変換するのは簡単です。最初にEmacs
Lispソースファイルのヘッダー行でlexical-binding
をt
にして、ファイルローカル変数を追加します(ファイルローカル変数を参照)。次に意図せずレキシカルにバインドしてしまわないように、ダイナミックなバインドをもつ必要がある変数が変数定義をもつことを各変数ごとにチェックします。
どの変数が変数定義をもつ必要があるか見つけるシンプルな方法は、ソースファイルをバイトコンパイルすることです。バイトコンパイルを参照してください。let
フォームの外側で非スペシャル変数が使用されていれば、バイトコンパイラーはフリーな変数にたいする参照や割り当てについて警告するでしょう。非スペシャル変数がバインドされているがlet
フォーム内で使用されていなければ、バイトコンパイラーは使用されないレキシカル変数に関して警告するでしょう。バイトコンパイラーは、スペシャル変数を関数の引数として使用している場合も問題を警告します。
フリー変換にたいする参照や割り当てに関する警告は、通常はその変数をダイナミックスコープにすべきだという明解なサインなので、その変数を最初に使用する前に適切なdefvar
を追加する必要があります。
使用されない変数についての警告は、それが(実際には別の関数で使用されているので)ダイナミックスコープを意図した変数だという良いヒントかもしれませんが、その変数が実際に未使用であり、単に削除可能であることを示しているのかもしれません。そのために、あなたはこれがいずれのケースなのかを調べて、それにもとづいてdefvar
を追加するか、あるいはその変数を完全に削除する必要があります。削除が不可能、あるいは望ましくない場合(典型的にはそれが正規の引数であり、呼び出し側すべての変更が不可能だったり望ましくない場合)には、それが使用されないと判っている変数であることをコンパイラーに示すために、変数名の先頭にアンダースコアを追加することもできます。
警告: これは事前通知なしに変更あるいは消滅するかもしれない実験的な機能です。
バイトコンパイラーは別のEmacs
Lispファイル内ではスペシャルであるようなレキシカル変数についても警告するかもしれません。これはしばしばdefvar
宣言の欠落を示しています。これは便利ですが3つのステップを要する幾分特殊なチェックを行います:
EMACS_GENERATE_DYNVARS
に非空の文字列をセットして、対象となりそうなスペシャル変数宣言をもつすべてのファイルをバイトコンパイルする。これは通常は同一パッケージ、関連するパッケージ、Emacsサブシステム内のすべてのファイルが該当する。この処理によりコンパイル済みEmacs
Lispファイルそれぞれにたいして、名前が.dynvarsで終わるファイルが生成される。
EMACS_DYNVARS_FILE
にはステップ2で作成した集約済みファイルがセットされる。
以下はUnixシェル上でmake
を使用してバイトコンパイルしたら何が行われるかを示した例です:
$ rm *.elc # 再コンパイルを強制 $ EMACS_GENERATE_DYNVARS=1 make # .dynvarsを生成 $ cat *.dynvars > ~/my-dynvars # .dynvarsを結合 $ rm *.elc # 再コンパイルを強制 $ EMACS_DYNVARS_FILE=~/my-dynvars make # チェック実施