Emacs 24.4中新建议系统的实际好处


53

Emacs 24.4带有新的建议系统。该NEWS文件说:

**新包装nadvice.el提供更轻巧的建议设施。它分层为:

*** add-function/ remove-function,可用于在任何函数承载的地方(例如过程过滤器或<foo>-function挂钩)添加/删除代码。

*** advice-add/ advice-remove添加/删除有关命名函数的建议,就像这样defadvice做。

问:此新软件包有哪些实际好处和启示?

我对解决以下问题的答案特别感兴趣:

  • 如果我仅使用建议自定义Emacs(而不是编写附加软件包),是否需要切换到新系统?它会在某个时候取代旧系统吗?

  • 什么究竟能做些什么与新的系统,我不能做到defadvice

  • 能够“在任何承载功能的地方添加/删除代码”的意义是什么?

Answers:


57

新的建议系统具有以下优点:

  • add-function:这是全新的功能,而这些功能根本不是defadvice的一部分。它是add-hook和之间的一种混合体defadvice。将来,期望更多的foo-function变量(通过修改add-function),更少的变量(通过foo-functions修改add-hook)。该功能是实施新建议系统的主要动力,该系统由一个错误报告触发,询问如何在不同程序包之间“共享”一个流程过滤器。

  • 实现简单:一旦add-function实现,仅需8KB即可实现该advice-add功能,该功能几乎带来了100KBadvice.el的所有功能。

  • 设计简单:defadvice具有各种概念,这些概念通常很难准确理解和/或很少使用。例如,“启用”和“激活”建议之间的区别。或“ pre”和/或“ compiled”的含义。处理时还存在一些古怪之处ad-do-it,例如看起来像变量引用而不是调用,或者需要(setq ad-return-value ...)显式而不是简单地返回值。

  • Defadvice遇到了宏扩展和编译的各种问题:通知的主体不是公开为“代码”(编译器和宏展开器会看到),而是公开为“数据”,随后将其组合起来构成一个表达式。因此,宏扩展发生得较晚(如果您使用诸如之类的东西,可能会引起意外(eval-when-compile (require 'foo))),并且很难准确地保留词法作用域。

至于您是否需要切换到新系统:我确实打算在将来的某个时候摆脱旧的defadvice,但是我认为这个未来还很遥远(它必须先移至lisp/obsolete,然后再移至到GNU ELPA)。


1
是否存在将nadvice.el添加到旧建议系统提供的相同参数修改功能的计划?
亚伦·米勒

不,在nadvice.el的上下文中,这几乎没有任何意义,因为advice函数是普通的普通函数。但是你可以使用:around的建议(或:filter-args:filter-result建议)来获得同样的效果。
Stefan

2
我不能,但是。假设我想建议一个包含两个参数的函数,仅替换第二个参数,以便建议的函数仍将根据其对第一个参数的交互形式进行提示。新建议似乎提供了几种不同的方法来替代建议功能的交互形式,但是我认为没有什么比这更细微差别了。
亚伦·米勒

@AaronMiller:请使其成为一个单独的SX问题,因此可以在没有人为限制SX注释的情况下进行讨论。
Stefan

emacs.stackexchange.com/q/19233/2162中完成。感谢您的跟进。(我也很想知道您在答案中提到的错误报告,但是却无法通过Google或邮件列表存档搜索找到它。您介意链接它吗?)
Aaron Miller

9

建议是正常功能的明显好处之一是,您可以使用来访问定义find-function

当前,在查看(新型)建议功能的帮助时,它提供了指向建议功能的帮助的链接,并从那里提供了到源的链接(通常是功能帮助)。

旧系统以内联方式提供了建议docstring,但是无法查看代码(我通常采用rgrep)。

(我个人希望看到显示帮助的旧方法和新方法的结合,因为我喜欢使用内联文档字符串,但是我确信这是可行的。)


2
是的,新的建议系统不允许您像defadvice这样添加到现有文档字符串中,这太糟糕了。请参阅此Emacs错误报告。这是缺点。
Drew

8

从文件头:

;;; Commentary:

;; This package lets you add behavior (which we call "piece of advice") to
;; existing functions, like the old `advice.el' package, but with much fewer
;; bells and whistles.

在我阅读本文时,主要目标是比旧的建议系统更简单,而不是拥有更多功能。阅读文档,似乎advice-add包含的一个子集defadvice的功能,同时add-function包含了指导非传统的功能,如处理过滤器的一些不错的功能(这可能是可能的defadvice,但我不知道如何)。

据我所知,defadvice它尚未正式被弃用,因此您可以随时继续使用它(如果您是软件包作者,则可能要继续使用它,直到24.4被广泛采用为止)。但是,听起来Emacs的作者希望最终完全迁移到新系统,因此慢慢切换可能是有意义的。



是。新的与众不同,仅此而已。是的,在那里有很多用途defadvice(并且将会继续存在)。
提请2014年

0

尽管在某些方面,它是由于简单的方法“新”的咨询系统,该系统的(更好的模块化和“胶水”) -我还没有看到这里提到的一件事已经在其他的答案被提及-是这样的:添加,合并,删除,重新排序等要容易得多。nadvice建议。

尽管nadvice需要一些帮助来简化此过程,但甚至可以交互地,动态地进行操作。我不知道这种方式对nadvice的其他使用(建议的交互组合),但是至少有一个这样的应用程序。我在Isearch +中利用了它,可以让您在搜索时添加和删除任意Isearch过滤谓词(过滤器)的组合。

IOW,就像您逐渐更改搜索模式一样,因此您可以使用多个过滤器快速优化搜索。

Isearch过滤是使用variable完成的isearch-filter-predicate,该变量已经存在了很长时间。但是,Isearch过滤器并不经常定义。它们通常是静态的,并且是针对给定上下文(例如Wdired)预定义的。用户至少以交互方式定义和使用它们并不容易。

仅存在一个变量,isearch-filter-predicate,所以改变真滤波意味着改变单个过滤器谓语,这相当于构成功能,结合谓词,缩小,膨胀,或以其他方式修改搜索。

但这正是nadvice擅长的。总而言之,nadvice在组合功能方面非常方便,因此可以轻松地交互式优化搜索过滤。(有关更多信息,请参见动态Isearch过滤。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.