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.