4

非常に奇妙な行動に出くわしたとき、私は別のSOの質問に答えようとしていました。ここに私の小さなテストケースがあります:

(make-variable-buffer-local
 (defvar my-override-mode-on-save nil
   "Can be set to automatically ignore read-only mode of a file when saving."))

(defadvice file-writable-p (around my-overide-file-writeable-p act)
  "override file-writable-p if `my-override-mode-on-save' is set."
  (or
   my-override-mode-on-save
   ad-do-it))

(defun my-override-toggle-read-only ()
  "Toggle buffer's read-only status, keeping `my-override-mode-on-save' in sync."
  (interactive)
  (setq my-override-mode-on-save (not my-override-mode-on-save))
  (toggle-read-only))

(defun tester-fn ()
  (interactive)
  (let ((xxx (file-writable-p "/tmp/foofoo"))
        (yyy (file-writable-p "/tmp/fooxxfoo")))
    (message (concat "XXX: " (if xxx "yes" "no") "   -   YYY: " (if yyy "yes" "no")))))

どこ:

  • /tmp/foofoo私がアクセスして実行my-override-toggle-read-onlyした読み取り専用ファイルです。
  • /tmp/fooxxfoo存在しません。
  • /tmpログインしているユーザーが書き込み可能です。

が に設定されtester-fnているバッファで実行すると、予期しない結果が得られます: . 他のバッファー (例: scratch ) で実行すると、期待される応答がミニバッファーで得られます。デバッガーを介してアドバイスを追跡すると、デバッガーが本来あるべきだと思うことを正確に実行し、期待する部分を実行し、期待する部分をスキップし、期待する値を返していることがわかります。ただし、デバッガーをトレースすると、非常に異なる値が返されることが示されます (変数が nil として評価される場合は& 、変数が非 nil として評価される場合は &) 。&リターンは、私が奇妙だと思うものです。my-override-mode-on-savetXXX: no - YYY: notester-fnXXX: no - YYY: yestester-fnniltnilnilnilnil

ここで何が起こっているのかわかりません。期待した結果が得られない理由を知っている人はいますか?

4

1 に答える 1

5

キーが1つ欠けていることを除けば、コードは見栄えがします。戻り値を適切に設定する必要があります。

(defadvice file-writable-p (around my-overide-file-writeable-p act)
  "override file-writable-p if `my-override-mode-on-save' is set."
  (setq ad-return-value
        (or
         my-override-mode-on-save
         ad-do-it)))

これはアドバイスマニュアルに記載されています。

于 2010-06-19T17:02:03.690 に答える