การแทนที่ 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 ทำงานแตกต่างกัน" มีคำแนะนำที่สองในข้อความเตือนนั้น ;-)
Malabarba

ฉันใช้อันเก่าแล้วก็เปลี่ยนชื่อใหม่ (เช่นmy-flet) และลบคำเตือนที่ล้าสมัยและใช้มันในแพ็คเกจใด ๆ ที่ก่อนหน้านี้ต้องการ 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
อย่างไรก็ตามโปรดจำไว้ในข้อแม้ของความคิดเห็นของ Yann Hodique ต่อบทความของ Malabarba: "โปรดทราบว่า Emacs 24.3.1มีข้อผิดพลาดที่ละเอียดอ่อนซึ่งcl-letfไม่ได้เป็นทางเลือกที่เหมาะสม (IIRC มันไม่ทำงานสำหรับfletสัญลักษณ์ที่ไม่ได้อยู่fboundp) คือเหตุผลว่าทำไมเวอร์ชั่นที่เข้ากันได้แบบย้อนหลังfletนั้นค่อนข้างซับซ้อน ... "
phils

12

Artur Malabarba เขียนขึ้นเมื่อเร็ว ๆ นี้ในการทำความเข้าใจ letf และวิธีการที่จะแทนที่ FLET

letfเป็นชื่อแทนcl-letfและในขณะที่เป็นไปได้มากที่สุดที่คุณต้องการมีข้อแม้เล็กน้อยที่อาร์เทอร์ชี้:

น่าเสียดายที่ cl-flet นั้นไม่เหมือนกับ flet ดั้งเดิม - มันเป็นคำศัพท์ไม่ใช่แบบไดนามิก

( nofletแพคเกจของ Nic มีฟังก์ชันการทำงานเพิ่มเติมตามบรรทัดเหล่านี้)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.