새로운 emacsen에서 flet을 올바르게 대체하는 것은 무엇입니까?


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. 어떻게 든 이맥스에게 경고를 무시하도록 지시하십시오.

  2. 내 자신의 롤 flet.

  3. noflet 또는 dflet을 사용하십시오 .

가장 좋은 방법은 무엇입니까?


3
"그러나 cl-flet은 다르게 작동합니다 . " 경고 메시지에 두 번째 제안이 있습니다. ;-)
Malabarba

나는 오래된 것을 가져 와서 이름을 바꿨고 (예 my-flet:) 쓸모없는 경고를 제거하고 이전에 flet이 필요한 패키지에서 사용했습니다.
lawlist

답변:


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
그러나 Malabarba의 기사에 마음에 얀 Hodique의 코멘트에서주의를 유지 : "이맥스 있습니다 24.3.1가 만드는 미묘한 버그가 cl-letf적절한 대안이되지를 (IIRC를, 그것을 위해 일을하지 않습니다 flet아직없는 문자 -ing fboundp) 어느. 이전 버전과 호환되는 버전이 flet약간 복잡한 이유 입니다. "
phils

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.