Semua informasi yang Anda butuhkan termasuk dalam C-h f add-function
yang menggambarkan mekanisme yang mendasari advice-add
.
Sistem saran baru pada dasarnya bertindak seperti mengganti definisi fungsi saat ini dengan fungsi yang dijelaskan dalam tabel di
C-h f add-function
, tergantung pada pilihan WHERE
argumen Anda, hanya pembersih demi melacak perilaku apa yang telah didefinisikan dalam file sumber apa.
Contoh dengan :around
opsi
Kasus yang paling umum adalah :around
opsi, jadi saya memberikan contoh untuk itu. (Mungkin lebih baik menggunakan WHERE
parameter khusus bila memungkinkan, tetapi Anda dapat mengganti satu sama lain dengan :around
fungsi yang setara
).
Sama seperti contoh, katakanlah Anda ingin men-debug beberapa penggunaan find-file
dan ingin print
daftar argumennya setiap kali dipanggil. Anda bisa menulis
(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)
Dengan implementasi baru ini, semua saran yang diperlukan dilewatkan sebagai argumen. ad-get-args
menjadi tidak perlu, karena argumen diteruskan ke fungsi saran sebagai argumen fungsi normal (untuk
WHERE
argumen yang masuk akal). ad-do-it
menjadi tidak perlu karena :around
saran mendapat sebagai fungsi argumen dan argumen, jadi (ad-do-it)
digantikan oleh formulir
(apply old-function arguments)
atau ketika Anda telah menyebutkan argumen
(funcall old-function first-arg second-arg)
yang lebih bersih karena tidak ada bentuk sihir yang terlibat. Mengubah argumen hanya terjadi dengan meneruskan nilai yang dimodifikasi ke OLD-FUNCTION
.
WHERE
Nilai lainnya
Dokumen add-function
berisi tabel semua tempat saran (atau "kombinator"), dan apa yang setara dengan mereka, dan menjelaskan fungsionalitas dalam hal lambda
berperilaku setara dengan fungsi yang disarankan:
`: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')
di mana FUNCTION adalah fungsi saran dan OLDFUN fungsi di mana saran ditambahkan. Jangan mencoba untuk memahami semuanya sekaligus, cukup pilih WHERE
simbol yang terdengar pas dan cobalah untuk memahaminya.
Atau gunakan saja :around
. Sejauh yang saya tahu satu-satunya keuntungan menggunakan WHERE
s khusus :around
untuk semuanya adalah bahwa Anda mendapatkan sedikit informasi lebih banyak dari mencari C-h f ADVISED-FUNCTION
sebelum membaca dokumentasi saran. Kecuali Anda berencana untuk menerbitkan kode yang berisi saran itu mungkin tidak masalah.
Bernama fungsi saran
Saya sarankan menggunakan fungsi bernama sebagai saran karena memberikan banyak keuntungan (beberapa dari mereka juga berlaku untuk menggunakan fungsi bernama untuk kait):
Itu muncul C-h f find-file
sebagai
:around advice: `my-find-file-advice-print-arguments'
menautkan ke definisi fungsi saran, yang seperti biasa berisi tautan ke file di mana ia didefinisikan. Jika saran telah didefinisikan sebagai lambda
bentuk langsung dalam advice-add
bentuk docstring akan ditampilkan inline (berantakan untuk dokumen panjang?) Dan tidak ada yang menunjukkan di mana itu didefinisikan.
Anda dapat menghapus saran dengan
(advice-remove #'find-file #'my-find-file-advice-print-arguments)
Anda dapat memperbarui definisi saran tanpa menjalankan kembali
advice-add
atau mengambil risiko untuk mengaktifkan versi lama (karena menjalankan
advice-add
dengan yang diubah lambda
akan diakui sebagai saran baru, bukan sebagai pembaruan ke yang lama).
Side komentar The #'function
notasi pada dasarnya setara dengan
'function
, kecuali bahwa itu membantu compiler byte mengidentifikasi simbol sebagai nama fungsi dan dengan demikian untuk mengidentifikasi fungsi yang hilang (misalnya karena kesalahan ketik).
M-x report-emacs-bug
. Beberapa pengembang terkadang lebih suka mengembangkan daripada mendokumentasikan. ;-) Adalah penting bahwa dokumen Emacs itu sendiri.