Semua informasi yang Anda butuhkan termasuk dalam C-h f add-functionyang 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 :aroundopsi
Kasus yang paling umum adalah :aroundopsi, jadi saya memberikan contoh untuk itu. (Mungkin lebih baik menggunakan WHEREparameter khusus bila memungkinkan, tetapi Anda dapat mengganti satu sama lain dengan :aroundfungsi yang setara
).
Sama seperti contoh, katakanlah Anda ingin men-debug beberapa penggunaan find-file
dan ingin printdaftar 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-argsmenjadi tidak perlu, karena argumen diteruskan ke fungsi saran sebagai argumen fungsi normal (untuk
WHEREargumen yang masuk akal). ad-do-itmenjadi tidak perlu karena :aroundsaran 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.
WHERENilai lainnya
Dokumen add-functionberisi tabel semua tempat saran (atau "kombinator"), dan apa yang setara dengan mereka, dan menjelaskan fungsionalitas dalam hal lambdaberperilaku 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 WHEREsimbol yang terdengar pas dan cobalah untuk memahaminya.
Atau gunakan saja :around. Sejauh yang saya tahu satu-satunya keuntungan menggunakan WHEREs khusus :arounduntuk 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-filesebagai
: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 lambdabentuk 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-addatau mengambil risiko untuk mengaktifkan versi lama (karena menjalankan
advice-adddengan yang diubah lambdaakan diakui sebagai saran baru, bukan sebagai pembaruan ke yang lama).
Side komentar The #'functionnotasi 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.