簡體   English   中英

如何編寫elisp輔助函數進行重構

[英]how to write elisp helper function for refactoring

我對emacs相當陌生,我不確定我理解Lisp的實際行為。

假設我有兩個功能

(add-hook 'python-mode-hook (lambda () add-to-list (make-local-variable 'company-backends) 'company-jedi)) (add-hook 'js2-mode-hook (lambda () add-to-list (make-local-variable 'company-backends) 'company-tern))

我寫了以下函數

(defun auto-complete (mode-hook backend) (add-hook mode-hook (lambda () add-to-list (make-local-variable 'company-backends) backend))) (auto-complete 'js2-mode-hook 'company-tern)

但它不起作用。 我在網上看了一下,發現那是因為elisp沒有關閉! 那么,我應該如何重構這兩個代碼塊?

add-to-list是一個函數,因此您需要在括號中使用它,例如(add-to-list...) 或使用funcallapply調用它。

Elisp 關閉。 請執行下列操作之一

使用文件局部變量lexical-bindingnil

(defun auto-complete (mode-hook backend)
  (add-hook mode-hook
    (lambda ()
       (add-to-list (make-local-variable 'company-backends) backend))))

使用詞匯綁定,您將獲得一個閉包,該閉包封裝了定義了變量backend的環境。 它在該環境中的值是創建閉包時的值,但是在使用匿名函數時該變量仍然存在-您可以將其用作變量。

請參見Elisp手冊,節點使用詞法綁定

無論lexical-binding的價值如何:

(defun auto-complete (mode-hook backend)
  (add-hook mode-hook
     `(lambda ()
       (add-to-list (make-local-variable 'company-backends) ',backend))))

在這種情況下, 沒有閉包 ,並且函數中沒有變量backend 而是在評估defun的時間和上下文中將該變量替換為其值 如果在調用匿名函數時不需要使用變量,並且只需要其值(在定義該函數時),則可以使用此變量。

如果使用閉包,則可以對匿名函數進行字節編譯。 如果您使用變量替換技術,那么它不能-在那種情況下,您不是在defun評估時(或用於字節編譯)創建匿名函數。 相反,您正在創建一個列表(lambda...) ,並且該列表稍后被解釋為一個函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM