`eval-when-compile`がファイルのロード時に実行され、.elcにバイトコンパイルされるのはなぜですか?


9

マクロ展開を回避する、またはバイトコンパイル中に未定義の変数に関する警告を解決するための一般的なイディオム:

(eval-when-compile
  (require 'cl-lib))

しかし、これrequire ....elcファイルにコンパイルされました!cl-eval-when(名前によると)適切なセマンティックスがあることがわかりました。

通常require、サイトファイルやpackage.el

たとえば.emacs、いくつかの外部マクロを使用して自分をバイトコンパイルしたいのですが、そのようなパッケージがない場合は黙ってパススルーします。

(cl-eval-when 'compile
  (condition-case err
      (require 'w3m-util)
    (error (byte-compile-warn "Failed by: %S" err))))
(w3m-util-DEPENDENT-CODE ...)

これを行う別の方法は次のとおりです。

(ignore-error
   (require 'w3m-util)
   (w3m-util-DEPENDENT-CODE ...))

しかし、今はトップレベルのフォームではありません...

そのeval-when-compile名前を適切に入力して、その名前から予期されないことをしますか?


FWIW、後者の2つのスニペットは同じ動作をしません。前者はw3m-DEPENDENT-CODE行方不明から保護しませんw3m-util
2015年

(when (require 'w3m-util nil t) (w3m-util-DEPENDENT-CODE...))
2015年

(when (require 'w3m-util nil t) ...)いいイディオムです!しかし、私.emacsはライブラリーではなく、完璧なファイルを作ろうとしています。したがって、自動ロードの助けを借りて、遅延した(要求に応じて)コードのロードを念頭に置いてください。このため、私はを広く使用していますがeval-after-loadrequireマクロ展開でバイトコンパイルを成功させるには、尋ねる必要があります。
ジヴェンコア2015年

回答:


9

Emacsに何eval-when-compileをすべきか尋ねましたか?

C-h f eval-when-compile ロード時にもargを評価することを伝えます:

eval-when-compile is a Lisp macro in `byte-run.el'.

(eval-when-compile &rest BODY)

Like ‘progn’, but evaluates the body at compile time if you’re compiling.
Thus, the result of the body appears to the compiler as a quoted
constant.  In interpreted code, this is entirely equivalent to
‘progn’, except that the value of the expression may be (but is
not necessarily) computed at load time if eager macro expansion
is enabled.

解釈するとのようなものだそうですprogn。そして、これを明示的に繰り返します。

関数またはマクロ名が動作を完全に反映することはほとんどありません。しかし、この場合は、と呼ばれる別の動作を探しているようですeval-only-when-compile


1
eval-only-when-compile名前名前へのポイントを理解するのに役立ちますeval-when-compile、ありがとう!
ジヴェンコア2015年

3

コンパイル段階でのみコードを評価eval-whenするには、1993-07-30にRMSによって日付が付けられたマクロを使用します。

cl-eval-when 2012-06-03にStefan Monnierから登場しましたが、Emacs 22.xでは利用できません(気になっている場合はそうです)。

たとえば、次のように削除したい場合Warning: assignment to free variable

(setq auto-revert-interval 2)

その行の上に追加するだけです:

(eval-when 'compile (require 'autorevert))

これは、.emacsファイルのバイトコンパイルにのみ役立つことに注意してください。ライブラリを開発する場合、ライブラリrequireファイルを個別に作成または分割して、必要な機能のみをロードする必要があります。


変数の警告を避けるために、あなただけの必要(defvar auto-revert-interval)
npostavs

1
defvarは多くの場合ソリューションを使用していますが、より強力なソリューションも探しています。名前を誤って入力したり、パッケージで定義を削除したりすると、そのような場合にコンパイルチェッカーがサイレントになります。
Givenkoa 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.