Quel est le remplacement correct pour flet sur un nouvel emacsen?


17

J'ai du code qui permet fletde changer temporairement le comportement des fonctions.

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

Cependant, le compilateur d'octets d'Emacs donne un avertissement:

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'.

Cependant, cl-fletfonctionne différemment et ne convient pas à certains cas d'utilisation, et je pense que c'est l'un de ces cas.

Les options que je peux voir sont:

  1. Dites à Emacs d'ignorer l'avertissement d'une manière ou d'une autre.

  2. Roulez moi-même flet.

  3. Utilisez noflet ou dflet .

Quelle est la meilleure approche?


3
"Cependant, cl-flet fonctionne différemment" . Il y a une deuxième suggestion dans ce message d'avertissement. ;-)
Malabarba

J'ai pris l'ancien et l'ai simplement renommé (par exemple, my-flet) et supprimé l'avertissement obsolète, et l'utiliser dans n'importe quel paquet qui nécessitait auparavant flet.
lawlist

Réponses:


13

Pour obtenir le même comportement que celui auquel vous êtes habitué flet, utilisez cl-letfpour modifier la valeur d'une fonction de symboles.

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

Si vous deviez rouler le vôtre flet, la méthode la plus simple serait la macro qui se développe en un cl-letfformulaire.

Edit: roulé

(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
Cependant, gardez à l'esprit la mise en garde du commentaire de Yann Hodique à l'article de Malabarba: "notez que Emacs 24.3.1 a un bug subtil qui cl-letfne constitue pas une alternative appropriée (IIRC, il ne fonctionne pas pour les fletsymboles -ing qui ne le sont pas déjà fboundp). c'est pourquoi une version rétrocompatible de fletest un peu ... compliquée . "
phils

12

Artur Malabarba l'a écrit récemment, dans Comprendre letf et comment il remplace flet .

letfest un alias pour cl-letf, et bien que ce soit probablement ce que vous voulez, il y a une petite mise en garde qu'Artur souligne:

Malheureusement, cl-flet n'est pas identique au flet d'origine - il est lexical, pas dynamique.

(Le nofletpackage de Nic fournit des fonctionnalités étendues dans ce sens.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.