Apa pengganti yang benar untuk flet di emacsen baru?

17

Saya memiliki beberapa kode yang digunakan fletuntuk sementara mengubah perilaku fungsi.

;; prevent changing the window
(flet ((pop-to-buffer (buffer &rest args)
                      (switch-to-buffer buffer)))
   (compilation-next-error-function n reset))

Namun, kompiler byte Emacs memberikan peringatan:

In ag/next-error-function:
ag.el:103:7:Warning: `flet' is an obsolete macro (as of 24.3); use either
    `cl-flet' or `cl-letf'.

Namun, cl-fletberfungsi secara berbeda dan tidak sesuai dengan beberapa kasus penggunaan, dan saya percaya ini adalah salah satu kasus tersebut.

Opsi yang bisa saya lihat adalah:

  1. Katakan pada Emacs untuk mengabaikan peringatan itu.

  2. Gulung sendiri flet.

  3. Gunakan noflet atau dflet .

Apa pendekatan terbaik?

Wilfred Hughes
sumber
3
"Namun, cl-flet bekerja secara berbeda" . Ada saran kedua dalam pesan peringatan itu. ;-)
Malabarba
Saya mengambil yang lama dan hanya mengganti nama (misalnya, my-flet) dan menghapus peringatan usang, dan menggunakannya dalam paket apa pun yang sebelumnya diperlukan flet.
hukum

Jawaban:

13

Untuk mendapatkan perilaku yang sama dengan yang Anda gunakan flet, gunakan cl-letfuntuk mengubah nilai fungsi simbol.

(cl-letf (((symbol-function 'pop-to-buffer)
           (lambda (buffer &rest _) (switch-to-buffer buffer))))
  (compilation-next-error-function n reset))

Jika Anda memutar sendiri flet, cara mudahnya adalah makro yang mengembang ke cl-letfformulir.

Edit: menggulungnya

(defmacro myflet (bindings &rest body)
  "Works like the old `flet'. Does not validate form structure."
  (declare (indent defun))
  `(cl-letf ,(mapcar (lambda (binding)
                       `((symbol-function ',(car binding))
                         (lambda ,(cadr binding) ,@(cddr binding))))
                     bindings)
     ,@body))

(myflet ((+ (&rest args) (apply '- args)))
  (+ 10 3 2)) ;; => 5
Jordon Biondo
sumber
3
Namun, ingatlah peringatan dari komentar Yann Hodique untuk artikel Malabarba: "perhatikan bahwa Emacs 24.3.1 memiliki bug halus yang membuat cl-letfbukan alternatif yang tepat (IIRC, itu tidak bekerja untuk fletsimbol yang belum ada fboundp). Yang mana itulah mengapa versi yang kompatibel dengan versi fletagak ... berbelit-belit . "
phils
12

Artur Malabarba menulis ini baru-baru ini, di Understanding letf dan bagaimana ia menggantikan flet .

letfadalah alias untuk cl-letf, dan sementara itu kemungkinan besar yang Anda inginkan, ada peringatan kecil yang ditunjukkan Artur:

Sayangnya, cl-flet tidak identik dengan flet asli — leksikal, bukan dinamis.

( nofletPaket Nic menyediakan fungsionalitas tambahan di sepanjang baris ini.)

sanityinc
sumber