新しい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つであると考えています。

私が見ることができるオプションは次のとおりです。

  1. Emacsに警告を無視するように伝えます。

  2. 私自身を転がしてくださいflet

  3. nofletまたはdfletを使用します。

最善のアプローチは何ですか?


3
「しかし、cl-fletの動作は異なります」。その警告メッセージには2番目の提案があります。;-)
Malabarba

古いものを取り、名前を変更して(例my-flet:)、廃止された警告を削除し、以前にfletを必要としていたパッケージでそれを使用しました。
法律家14年

回答:


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さんのコメントからの警告:「Emacsのことに注意してください24.3.1が作る微妙なバグがありcl-letfません、適切な代替(IIRCのため、そうでない仕事fletまだなっていないシンボル-ing fboundp。)をどのの下位互換バージョンがflet少し... 複雑な理由です。」
フィル14年

12

Artur Malabarbaは、letfとそれがfletを置き換える方法理解するに、最近これを書きました

letfはのエイリアスでありcl-letf、おそらくあなたが望むものですが、Arturが指摘する小さな警告があります:

残念ながら、cl-fletは元のfletと同一ではありません。レキシカルであり、動的ではありません。

(Nicのnofletパッケージは、これらのラインに沿って拡張機能を提供します。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.