Next: Compiler Errors, Previous: Dynamic Loading, Up: Byte Compilation [Contents][Index]
これらの機能により、プログラムのコンパイル中に評価されるコードを記述できます。
このフォームは、それを含むコードがコンパイルされるとき、および(コンパイルされているかいないかに関わらず)実行されるときの両方で、bodyが評価されるようにマークします。
bodyを別のファイルに配し、そのファイルをrequire
で参照すれば、同様の結果が得られます。これはbodyが大きいとき望ましい方法です。事実上、require
は自動的にeval-and-compile
され、そのパッケージはコンパイル時と実行時の両方でロードされます。
autoload
も実際はeval-and-compile
されます。これはコンパイル時に認識されるので、そのような関数の使用により警告“not
known to be defined”は生成されません。
ほとんどのeval-and-compile
の使用は、完全に妥当であると言えます。
あるマクロがマクロの結果を構築するためのヘルパー関数をもち、そのマクロがそのパッケージにたいしてローカルと外部の両方で使用される場合には、コンパイル時と後の実行時にそのヘルパー関数を取得するために、eval-and-compile
を使用すべきです。
関数がプログラム的に(fset
で)定義されている場合には、それがコンパイル時、同様に実行時に行われるように使用でき、それらの関数への呼び出しはチェックされます(“not
known to be defined”の警告は抑えられます)。
このフォームは、bodyがコンパイル時に評価され、コンパイルされたプログラムがロードされるときは評価されないようにマークします。コンパイラーによる評価の結果は、コンパイル済みのプログラム内の定数となります。ソースファイルをコンパイルではなくロードした場合、bodyは通常どおり評価されます。
生成するために何らかの計算が必要な定数がある場合、eval-when-compile
はコンパイル時にそれを行なうことができます。たとえば、
(defvar my-regexp (eval-when-compile (regexp-opt '("aaa" "aba" "abb"))))
他のパッケージを使用しているが、そのパッケージのマクロ(バイトコンパイラーはそれらを展開します)だけが必要な場合、それらを実行せずにコンパイル用にロードさせるためにeval-when-compile
を使用できます。たとえば、
(eval-when-compile (require 'my-macro-package))
これらの事項は、マクロおよびdefsubst
関数がローカルに定義され、そのファイル内だけで使用されることを要求します。これらは、そのファイルのコンパイルに必要ですが、コンパイル済みファイルの実行には、ほとんどの場合必要ありません。たとえば、
(eval-when-compile (unless (fboundp 'some-new-thing) (defmacro 'some-new-thing () (compatibility code))))
これは大抵他のバージョンのEmacsとの互換性にたいする保証だけのためのコードにたいして有用です。
Common Lispに関する注意: トップレベルでは、eval-when-compile
はCommon
Lispのイディオム(eval-when (compile eval)
…)
に類似しています。トップレベル以外では、Common
Lispのリーダーマクロ‘#.’(ただし解釈時を除く)が、eval-when-compile
と近いことを行います。