5

同じことを何度も繰り返すというコードの傾向に気付いた(with-current-buffer ....ので、そのマクロ定義に基づいてマクロを定義することにしましたwith-current-buffer-これは私がこれまでに持っているものです:

(defmacro with-assembla-buffer(asm-buffer-name heading-str &rest body)
  "Create buffer with name of ASM-BUFFER-NAME, or uses it if exists,                                                                                                      
   preps it with readonly/erase/heading - executes `body' - then puts                                                                                                     
   readonly back on, goes to beginning of buffer, and switches to it."
  (with-current-buffer (get-buffer-create asm-buffer-name)
    (assembla-mode)
    (toggle-read-only -1)
    (erase-buffer)
    (insert (format "-- %s --------------------" heading-str))
    (newline)
    `(progn ,@body)
    (toggle-read-only 1)
    (goto-char (point-min))
    (switch-to-buffer (current-buffer))))

これの本体は決して実行されませんが、defun代わりに切り替えられた場合defmacroは完全に機能します。body が実行されない理由は別として、私のもう 1 つの質問は、これは defun よりもマクロとして意味がありますか?

4

1 に答える 1

4

マクロはコードを生成することを思い出してください。あなたのマクロはそうではないようです。サンプル呼び出しのマクロ展開を確認してください。マクロをデバッグする最初のステップは、一部のコードのマクロ展開を確認す​​ることです。

....

(with-current-buffer (get-buffer-create asm-buffer-name)

上: なぜこれはソース コードではなく、マクロ内のコードなのですか? このコードは、マクロが展開されたときに実行され、生成されたコードには表示されません。あなたはおそらくそれをバッククォートしたいと思うでしょう。

  (assembla-mode)
  (toggle-read-only -1)
  (erase-buffer)
  (insert (format "-- %s --------------------" heading-str))
  (newline)

   `(progn ,@body)

上:これはあなたが望むことをしません。このフォームだけでなく、生成したいすべてのコードをバッククォートする必要があります。

于 2012-11-18T21:57:11.770 に答える