【问题标题】:How to advise primitives in Emacs如何在 Emacs 中建议原语
【发布时间】:2010-06-19 14:44:23
【问题描述】:

当我遇到一些非常奇怪的行为时,我正试图回答 another SO question。这是我的小测试用例:

(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 可由我登录的用户写入。

如果我在将my-override-mode-on-save 设置为t 的缓冲区中运行tester-fn,则会得到意想不到的结果:XXX: no - YYY: no。如果我在其他缓冲区(例如 scratch)中运行 tester-fn,我会在小缓冲区中得到预期的响应:XXX: no - YYY: yes。通过调试器跟踪建议表明它正在做我认为它应该做的事情,执行我期望它执行的部分,跳过我期望它执行的部分,返回我期望它的值。但是,通过调试器跟踪 tester-fn 会显示返回的值非常不同(nil & t 如果变量评估为 nil,nil & nil 如果变量评估为非 nil)。 nil & nil 的回报真的让我觉得很奇怪。

我不知道这里发生了什么。有人知道为什么我没有得到预期的结果吗?

【问题讨论】:

    标签: emacs elisp advising-functions defadvice


    【解决方案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)))
    

    这在advice manual 中有记录。

    【讨论】:

    • 我一直认为ad-return-value 是用来覆盖返回值的,而不是设置它(手册也这么说)。但这确实是缺失的部分——谢谢!
    • 不同之处(对我来说)是假设返回值是正常的(即最后评估的表达式),而ad-return-value 将用于改变它。
    • @JoeCasadonte 啊,我总是将建议解释为给你改变行为的钩子,但是(引用)“After-advice 和 around-advice 可以通过设置 ad-return-value 来覆盖返回值。 "但我可以看到你的 POV。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多