Вся необхідна інформація міститься в C-h f add-function
якій описується основний механізм роботи advice-add
.
Нова система порад в основному діє як заміна поточного визначення функції функцією, описаною в таблиці в
C-h f add-function
, залежно від вашого вибору WHERE
аргументу, лише чистішою для того, щоб відстежувати, яка поведінка була визначена в якому вихідному файлі.
Приклад з :around
варіантом
Найбільш загальним випадком є :around
варіант, тому я наводжу приклад для цього. (Можливо, краще використовувати виділені WHERE
параметри, коли це можливо, але ви можете замінити один одного на еквівалентну
:around
функцію).
Як приклад, скажемо, що ви хочете налагодити деяке використання find-file
та хочете в print
його аргументальний список кожного разу, коли він викликається. Ви могли написати
(defun my-find-file-advice-print-arguments (old-function &rest arguments)
"Print the argument list every time the advised function is called."
(print arguments)
(apply old-function arguments))
(advice-add #'find-file :around #'my-find-file-advice-print-arguments)
З цією новою реалізацією все необхідне поради передається як аргумент. ad-get-args
стає непотрібним, оскільки аргументи передаються функції поради як нормальні аргументи функції (для
WHERE
аргументів, для яких це має сенс). ad-do-it
стає непотрібним, оскільки :around
порада отримує як аргументи функцію та аргументи, тому (ad-do-it)
її замінюють формою
(apply old-function arguments)
або коли ви назвали аргументи
(funcall old-function first-arg second-arg)
яка чистіша, оскільки ніяких магічних форм не задіяно. Змінення аргументів відбувається просто шляхом передачі змінених значень до OLD-FUNCTION
.
Інші WHERE
значення
Документальний рядок add-function
містить таблицю всіх місць для отримання порад (або "комбінаторів") та того, що вони еквівалентні, та пояснює функціональність з точки зору lambda
поведінки, еквівалентної рекомендованій функції:
`:before' (lambda (&rest r) (apply FUNCTION r) (apply OLDFUN r))
`:after' (lambda (&rest r) (prog1 (apply OLDFUN r) (apply FUNCTION r)))
`:around' (lambda (&rest r) (apply FUNCTION OLDFUN r))
`:override' (lambda (&rest r) (apply FUNCTION r))
`:before-while' (lambda (&rest r) (and (apply FUNCTION r) (apply OLDFUN r)))
`:before-until' (lambda (&rest r) (or (apply FUNCTION r) (apply OLDFUN r)))
`:after-while' (lambda (&rest r) (and (apply OLDFUN r) (apply FUNCTION r)))
`:after-until' (lambda (&rest r) (or (apply OLDFUN r) (apply FUNCTION r)))
`:filter-args' (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))
`:filter-return'(lambda (&rest r) (funcall FUNCTION (apply OLDFUN r)))
(cited from `C-h f add-function')
де FUNCTION - функція поради, а OLDFUN - функція, де порада додана. Не намагайтеся зрозуміти їх усі одразу, просто виберіть WHERE
символ, який відповідає звуку, і спробуйте зрозуміти його.
Або просто використовувати :around
. Наскільки я можу сказати, єдиною перевагою використання спеціалізованих WHERE
s over :around
для всього є те, що ви отримуєте трохи більше інформації, шукаючи до C-h f ADVISED-FUNCTION
того, як прочитати доктрину поради. Якщо ви не плануєте публікувати код, що містить поради, це, мабуть, не має значення.
Названі функції поради
Я рекомендую використовувати названі функції як пораду, оскільки це надає багато переваг (деякі з них стосуються також використання названих функцій для гачків):
Він відображається C-h f find-file
як
:around advice: `my-find-file-advice-print-arguments'
посилання на визначення функції поради, яка, як правило, містить посилання на файл, де він був визначений. Якби порада була визначена як lambda
форма безпосередньо у advice-add
формі, докстринг відображатиметься в рядку (безлад для довгих доктрингів?), І ніщо б не вказувало, де воно було визначене.
Можна видалити поради за допомогою
(advice-remove #'find-file #'my-find-file-advice-print-arguments)
Ви можете оновити визначення поради, не відкладаючи
advice-add
або не ризикуючи підтримувати стару версію активною (оскільки запущена
advice-add
зі зміною lambda
буде визнана новою порадою, а не як оновлення до старої).
Бічне зауваження#'function
позначення в основному еквівалентно
'function
, за винятком того, що він допомагає байтам компілятору визначити символи, імена функцій і , таким чином , щоб виявити відсутні функції (наприклад , з - за помилки).
M-x report-emacs-bug
. Деякі розробники іноді віддають перевагу розробці над документуванням. ;-) Важливо, щоб Emacs документував сам.