Wie kann ich einen unbenannten Rat entfernen?

12

Ich hatte Spaß daran, einer Funktion einige Ratschläge hinzuzufügen:

(advice-add 'executable-find :around
            (lambda (f &rest args)
              (apply g args)))
               ;;;   ^

Autsch, ein Tippfehler. Es wurde behoben und der obige Code erneut ausgewertet. Aber jetzt habe ich sowohl den "korrigierten" als auch den "kaputten" Rat bezüglich dieser Funktion.

Wie werde ich diese los? Vorausgesetzt, dass advice-removeentweder das Funktionsobjekt oder der Around-Rat benötigt (der hier leer ist)?

(Natürlich kann ich einfach beenden und neu starten, aber es gibt noch einen anderen Weg, oder?)

Daniel Jour
quelle

Antworten:

7

Sie können auch anrufen advice-removemit dem gleichen Lambda - Ausdruck, dh ersetzen advice-addmit advice-removeund löschen :around, dann C-x C-e.

Xuchunyang
quelle
Das funktioniert! Ich dachte, es würde nicht so sein, ich nahm an, dass (1) jedes Mal, wenn Sie ein Lambda-Formular auswerten, Sie eine neue Funktion erhalten, die nicht eqmit den vorherigen übereinstimmt, (2) das Entfernen von Ratschlägen die Funktion vergleicht, die Sie an die Ratschläge übergeben, bis sie gefunden wird eine, die dazu gehört eqund das entfernt, (3) selbst wenn ein Ratschlag-Entfernen einen anderen Test verwendet, equalwürde es immer noch nicht funktionieren, weil sich verschiedene Bewertungen einer Lambda-Form nicht equalgegenseitig würden . Es stellt sich heraus, dass (1) richtig ist, aber (2) und (3) falsch sind: Ratschläge entfernen equalund lambdazweimal bewerten, führt zu equalErgebnissen!
Omar
Als ich die Frage stellte, bemerkte ich, dass ich keine Antwort zurück akzeptierte. Ich wähle Ihre, weil es die IMO ist, die in der Situation am hilfreichsten ist.
Daniel Jour
11

Es gibt eine advice-mapc, die alle Ratschläge einer Funktion durchläuft und auf jede eine bestimmte Funktion anwendet. Damit ist es einfach, alle Ratschläge zu entfernen:

(advice-mapc
  (lambda (adv prop)
    (advice-remove 'executable-find adv))
  'executable-find)

Dies könnte erweitert werden, um nur Hinweise zu entfernen, die keine nameEigenschaft haben, indem im zweiten ( props) Argument (das eine Liste ist) nach solchen gesucht wird, denen nichts mit dem Schlüssel verknüpft ist name.

Daniel Jour
quelle
Ja. Und die Verwendung namevon erleichtert das Entfernen.
Drew
1

Hier ist ein Code, der Ihnen dabei hilft, interaktiv zu arbeiten.

Dies definiert zwei Funktionen. Die erste Funktion erhält die Liste aller Hinweise zu einem bestimmten Symbol, die zweite Funktion fragt interaktiv nach einem Symbol und einem Hinweis zu diesem Symbol und entfernt dann das letztere aus dem ersteren. Da dies alles mit der Fertigstellung geschieht, ist es (für mich) einfacher als das Einfügen des Lambda-Ausdrucks zu kopieren.

(defun yf/advice-list (symbol)
  (let (result)
    (advice-mapc
     (lambda (ad props)
       (push ad result))
     symbol)
    (nreverse result)))

(defun yf/kill-advice (symbol advice)
  "Kill ADVICE from SYMBOL."
  (interactive (let* ((sym (intern (completing-read "Function: " obarray #'yf/advice-list t)))
                      (advice (let ((advices-and-their-name
                                     (mapcar (lambda (ad) (cons (prin1-to-string ad)
                                                                ad))
                                             (yf/advice-list sym))))
                                (cdr (assoc (completing-read "Remove advice: " advices-and-their-name nil t)
                                            advices-and-their-name)))))
                 (list sym advice)))
  (advice-remove symbol advice))
Junger Frosch
quelle