Was ist der richtige Ersatz für Flet on New Emacsen?

17

Ich habe einen Code , der verwendet wird flet, um das Verhalten von Funktionen vorübergehend zu ändern.

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

Der Byte-Compiler von Emacs gibt jedoch eine Warnung aus:

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

Funktioniert jedoch cl-fletanders und eignet sich nicht für einige Anwendungsfälle. Ich glaube, dies ist einer dieser Fälle.

Die Optionen, die ich sehen kann, sind:

  1. Sagen Sie Emacs, er soll die Warnung irgendwie ignorieren.

  2. Roll mein eigenes flet.

  3. Verwenden noflet oder dflet .

Was ist der beste Ansatz?

Wilfred Hughes
quelle
3
"Cl-flet funktioniert jedoch anders" . In dieser Warnmeldung gibt es einen zweiten Vorschlag. ;-)
Malabarba
Ich habe die alte genommen und sie einfach umbenannt (z. B. my-flet) und die veraltete Warnung entfernt und in jedem Paket verwendet, für das zuvor eine Flotte erforderlich war.
Gesetzesliste

Antworten:

13

Um das gleiche Verhalten erhalten Sie mit gewohnt sind flet, verwenden , cl-letfum ein Zeichen Funktionswert zu ändern.

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

Wenn Sie Ihre eigenen würfeln fletwürden, wäre der einfache Weg ein Makro, das sich zu einem cl-letfFormular erweitert.

Bearbeiten: rollte es

(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
Jordon Biondo
quelle
3
Beachten Sie jedoch den Vorbehalt von Yann Hodiques Kommentar zu Malabarbas Artikel: "Beachten Sie, dass Emacs 24.3.1 einen subtilen Fehler aufweist, der cl-letfkeine richtige Alternative darstellt (IIRC funktioniert nicht für fletSymbole, die noch nicht vorhanden sind fboundp). Welche Aus diesem Grund ist eine abwärtskompatible Version von fletein bisschen ... verworren . "
Phils
12

Artur Malabarba schrieb dies kürzlich in " Letf verstehen und wie es Flet ersetzt" .

letfist ein Alias ​​für cl-letfund obwohl es höchstwahrscheinlich das ist, was Sie wollen, gibt es eine kleine Einschränkung, auf die Artur hinweist:

Leider ist cl-flet nicht identisch mit der Originalflotte - es ist lexikalisch und nicht dynamisch.

(Nic's nofletPaket bietet erweiterte Funktionen in diesem Sinne.)

sanityinc
quelle