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)中运行,我会在 minibuffer: 中得到预期的响应。通过调试器跟踪建议表明它正在做我认为它应该做的事情,执行我期望它执行的部分,跳过我期望它执行的部分,返回我期望它的值。但是,通过调试器进行跟踪显示返回的值非常不同(如果变量评估为 nil,则 &如果变量评估为非 nil)。& return 真的让我觉得很奇怪。my-override-mode-on-savetXXX: no - YYY: notester-fnXXX: no - YYY: yestester-fnniltnilnilnilnil

我不知道这里发生了什么。任何人都知道为什么我没有得到我期望的结果?

4

1 回答 1

5

您的代码看起来不错,除了缺少一个键。您需要适当地设置返回值:

(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 回答