Яка правильна заміна flet на новий emacsen?


17

У мене є якийсь код, який використовується fletдля тимчасової зміни поведінки функцій.

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

Однак компілятор байтів Emacs попереджає:

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'.

Однак cl-fletпрацює інакше і не підходить для деяких випадків використання, і я вважаю, що це один із таких випадків.

Можливі варіанти:

  1. Скажіть Emacs якось ігнорувати попередження.

  2. Покатайте мою власну flet.

  3. Використовуйте noflet або dflet .

Який найкращий підхід?


3
"Однак, cl-flet працює інакше" . У цьому попереджувальному повідомленні є друга пропозиція. ;-)
Малабарба

Я взяв старий і просто перейменував його (наприклад, my-flet) і видалив застаріле попередження, і використав це в будь-якому пакеті, який раніше вимагав флет.
законник

Відповіді:


13

Щоб отримати таку саму поведінку, з якою ви звикли flet, використовуйте cl-letfдля зміни значення функції символів.

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

Якби ви прокрутили свій власний flet, найпростішим способом був би макрос, який розширюється до cl-letfформи.

Редагувати: прокат

(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

3
Однак майте на увазі застереження від коментаря Янна Ходіка до статті Малабарби: "зауважте, що в Emacs 24.3.1 є тонка помилка, яка cl-letfне є належною альтернативою (IIRC, він не працює для flet-ing символів, які ще не є fboundp). ось чому сумісна з відсталою версією fletдещо ... перекручена ".
phils

12

Артур Малабарба написав це нещодавно в " Розуміння літ" і як він замінює флет .

letfє псевдонімом cl-letf, і хоча це, швидше за все, те, що ви хочете, є незначний застереження, яке Артур вказує:

На жаль, cl-flet не тотожний оригінальному флету - він лексичний, а не динамічний.

( nofletПакет Ніка забезпечує розширену функціональність у цих напрямках.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.