我有一个已知变量的列表和带有nil参数列表的相应函数,在body中它使用已知的非参数(或全局)变量。
例如。
(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而不是我也想知道它。)
答案 0 :(得分:3)
您可以使用letf
(最近的Emacs中的cl-letf
)执行此操作。它绑定let
之类的值,但允许'places'或'generalized variables'以及简单的变量名。
(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 :(得分:1)
在Common Lisp中,这是由PROGV
提供的 - 给定变量符号的变量的动态绑定。
GNU Emacs在Common Lisp仿真中应该有PROGV
。
答案 2 :(得分: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))))))