defalias と defadvice を使って似た関数を作る

昨日のエントリid:higepon さんにやたらと感謝されたはいいが、「ひげぽん OSとか作っちゃうかMona- - defadvice楽しい」のコメント欄で

  • 一時的に挙動を変更するのに defadvice を使うのは行儀がよくない
  • compile で例外が送出された場合に advice が無効にならないので unwind-protect を使わないといけない

とダメだしを食らった。確かに。
で、それを踏まえてこんなんしてみた。

(defalias 'silent-compile 'compile)
(defadvice silent-compile
  (around force-silent-compile activate)
  (let ((orig-yes-or-no-p (symbol-function 'yes-or-no-p)))
    (defun yes-or-no-p (prompt) t)
    (unwind-protect
        ad-do-it
      (fset 'yes-or-no-p orig-yes-or-no-p))))

本当は silent-compile から compile を呼び出せばいいかと思ったのだけど、interactive な引数の扱いが面倒だったので defalias で定義して defadvice で advice を引っ掛けるようにした。silent-compile のくせに M-x silent-compile だとコンパイルコマンド聞かれるけど。
M-x silent-compile って呼ぶ必要がないなら

(defun silent-compile (command &optional comint)
  (let ((orig-yes-or-no-p (symbol-function 'yes-or-no-p)))
    (defun yes-or-no-p (prompt) t)
    (unwind-protect
        (compile command comint)
      (fset 'yes-or-no-p orig-yes-or-no-p))))

でいいんだけどね。