什么是新emacsen上flet的正确替代品?


17

我有一些代码,使用flet临时更改的功能的行为。

;; prevent changing the window
(flet ((pop-to-buffer (buffer &rest args)
                      (switch-to-buffer buffer)))
   (compilation-next-error-function n reset))

但是,Emacs的字节编译器发出警告:

In ag/next-error-function:
ag.el:103:7:Warning: `flet' is an obsolete macro (as of 24.3); use either
    `cl-flet' or `cl-letf'.

但是,cl-flet工作方式不同,因此不适合某些用例,我认为这是其中一种。

我可以看到的选项是:

  1. 告诉Emacs以某种方式忽略该警告。

  2. 自己滚flet

  3. 使用nofletdflet

最好的方法是什么?


3
“但是,cl-flet的工作原理不同”。该警告消息中还有第二个建议。;-)
马拉巴巴2014年

我选择了旧的并重新命名(例如my-flet),并删除了过时的警告,并将其用于以前需要flet的任何软件包中。
法律列表

Answers:


13

要获得与您习惯的相同的行为flet,请使用cl-letf更改符号函数值。

(cl-letf (((symbol-function 'pop-to-buffer)
           (lambda (buffer &rest _) (switch-to-buffer buffer))))
  (compilation-next-error-function n reset))

如果要自己滚动flet,则简单的方法是将宏扩展为cl-letf表单。

编辑:滚动

(defmacro myflet (bindings &rest body)
  "Works like the old `flet'. Does not validate form structure."
  (declare (indent defun))
  `(cl-letf ,(mapcar (lambda (binding)
                       `((symbol-function ',(car binding))
                         (lambda ,(cadr binding) ,@(cddr binding))))
                     bindings)
     ,@body))

(myflet ((+ (&rest args) (apply '- args)))
  (+ 10 3 2)) ;; => 5

3
但是,请记住从Yann Hodique的评论到Malabarba的文章的警告:“请注意,Emacs 24.3.1具有一个细微的错误,cl-letf不能作为适当的替代方法(IIRC,它不适用于flet-ing尚未存在的符号fboundp)。这就是为什么向后兼容的版本flet有点... 令人费解的原因。”
菲利浦斯,2014年

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.