2013-04-13 38 views
2

我有一個已知變量和具有nil參數列表的相應函數的列表,它內部使用已知的非參數(或全局)變量。在Elisp中如何動態地賦值給一個也是動態選擇的變量(在表單中)

例如,

(defun funA() 
    (message "%s" varA)) 

(defun funB() 
    (message "%s" varB)) 

... 

(setq alist 
     '((varA . funA) 
     (varB . funB) 
     ... 
     )) 

alist中的相似元素可以動態添加/刪除。

我想在另一個函數中運行所有這些函數,其中已知變量的值以LET形式動態分配。

(defun call-each-fun-of-alist() 
    (dolist (e alist) 
    (let (((car e) (read-from-minibuffer "value: "))) 
     (funcall (cdr e))))) 

(是的,它會拋出錯誤,但我想類似的事情,可能不EVAL)

對於ALIST的已知因素(如第一我可以做

(let ((varA (read-from-minibuffer "value: "))) 
    (funcall (cdr (assoc 'varA alist)))) 

但ALIST是動態更新,我什麼運行在alist 所有功能和相應的變量的值會動態地。

請讓我知道我如何一個定義

call-each-fun-of-alist 

(不一定,但沒有調用EVAL內調用每個-樂趣的-ALIST,如果沒有可能不EVAL比我想知道它也。)

回答

3

你可以用letf(最近的Emacs中的cl-letf)做到這一點。它綁定像let這樣的值,但允許「位置」或「廣義變量」以及簡單的變量名稱。

(defun call-each-fun-of-alist() 
    (cl-dolist (e alist) 
    (cl-destructuring-bind (variable . function) e 
     (cl-letf (((symbol-value variable) 
       (read-from-minibuffer 
        (format "value for %s: " 
          variable)))) 
     (funcall function))))) 

需要注意的是,除非在alist命名變量以前被宣佈爲使用defvar動態變量,這將失敗,出現錯誤。查閱Elisp手冊中的「廣義變量」以獲取更多信息。

另一種解決方案是使用cl-progv,這需要變量名和值的平行的列表動態綁定:

(defun call-each-fun-of-alist() 
    (cl-dolist (e alist) 
    (cl-destructuring-bind (variable . function) e 
     (cl-progv 
      (list variable) 
      (list (read-from-minibuffer 
       (format "value for %s: " 
         variable))) 
     (funcall function))))) 
1

在Common Lisp的,這是由PROGV提供 - 給定變量的符號的變量的動態綁定。

GNU Emacs在其Common Lisp仿真中應該有PROGV

+0

感謝您的幫助 – Sharad

0

這是你所需要的 - 無需progv或破壞綁定的東西:

(defun call-each-fun-of-alist (alist) 
    (dolist (e alist) 
    (set (car e) (read-from-minibuffer "value: ")) 
    (funcall (cdr e)))) 

(defvar my-alist '((varA . funA) (varB . funB))) 
(call-each-fun-of-alist my-alist) 

或者,如果你真的想看到一個let出於某種原因結合:

(defun call-each-fun-of-alist (alist) 
    (dolist (e alist) 
    (eval `(let ((,(car e) (read-from-minibuffer "value: "))) 
      (funcall (cdr e))))))