Come posso rimuovere un consiglio senza nome?


12

Mi stavo divertendo aggiungendo qualche consiglio a una funzione:

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

Ahi, un errore di battitura. Risolto il problema e valutato di nuovo sopra il codice. Ma ora ho entrambi i consigli "corretti" e "rotti" su quella funzione.

Come posso liberarmene? Dato che è advice-removenecessario l'oggetto funzione o il consiglio around (che è vuoto qui)?

(Ovviamente posso solo uscire e riavviare, ma c'è un altro modo, vero?)

Risposte:


7

Puoi anche chiamare advice-removecon la stessa espressione lambda, ovvero sostituire advice-addcon advice-removeed eliminare :around, quindi C-x C-e.


Questo funziona! Pensavo che non lo fosse, supponevo che (1) ogni volta che valuti un modulo lambda ottieni una nuova funzione non eqrispetto alle precedenti, (2) avviso-rimozione confronta la funzione che passi ai consigli finché non trova uno che lo è eqe lo rimuove, (3) anche se un consiglio-rimuovi utilizzava un test diverso, come equal, comunque, non avrebbe funzionato, perché diverse valutazioni di una forma lambda non si sarebbero equalscambiate. Si scopre che (1) è corretto, ma (2) e (3) sono sbagliati: consiglia di rimuovere gli usi equale valutare lambdadue volte lo stesso produce equalrisultati!
Omar,

Ho notato che non ho accettato una risposta quando ho posto la domanda. Scelgo il tuo perché è l'IMO più utile nella situazione.
Daniel Jour,

11

C'è advice-mapc, che cerchiamo di scorrere su tutti i consigli di alcune funzioni, applicando una determinata funzione a ciascuna. Con esso, è facile rimuovere tutti i consigli:

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

Questo potrebbe essere esteso per rimuovere solo i consigli che non hanno una nameproprietà cercando nel secondo propsargomento () che è un elenco) quelli che non hanno qualcosa associato alla chiave name.


Sì. E l'utilizzo di a namesemplifica la rimozione.
Disegnato

1

Ecco un po 'di codice per aiutarti a fare proprio questo, in modo interattivo.

Questo definisce due funzioni. La prima funzione ottiene l'elenco di tutti i consigli su un dato simbolo, la seconda funzione richiede interattivamente un simbolo e un consiglio su quel simbolo, quindi rimuove il secondo dal primo. Poiché tutto ciò accade con il completamento, è più facile (per me) che copiare incollando l'espressione lambda.

(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))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.