在Elisp中,如何将值动态分配给也动态选择的变量(以let形式)

在Elisp中,如何将值动态分配给也动态选择的变量(以let形式),lisp,elisp,Lisp,Elisp,我有一个已知变量和对应函数的列表,其中包含nil参数列表,它在主体内部使用已知的非参数(或全局)变量 例如 (defun funA () (message "%s" varA)) (defun funB () (message "%s" varB)) ... (setq alist '((varA . funA) (varB . funB) ... )) 可以动态添加/删除列表中的类似元素 我想在另一个函数中运行所有这些

我有一个已知变量和对应函数的列表,其中包含nil参数列表,它在主体内部使用已知的非参数(或全局)变量

例如

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

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

...

(setq alist
      '((varA . funA)
        (varB . funB)
        ...
        ))
可以动态添加/删除列表中的类似元素

我想在另一个函数中运行所有这些函数,其中已知变量的值以LET形式动态分配

(defun call-each-fun-of-alist ()
  (dolist (e alist)
    (let (( (car e)  (read-from-minibuffer "value: ") ))
      (funcall (cdr e)))))
(是的,它会抛出错误,但我想做类似的事情,没有EVAL也可能)

对于已知的元素(比如我能做的第一件事)

(let ((varA (read-from-minibuffer "value: ")))
  (funcall (cdr (assoc 'varA alist))))
但是alist是动态更新的,我知道如何在alist中运行所有函数 相应变量的值将动态出现

请让我知道如何定义

call-each-fun-of-alist

(不一定,但不需要调用EVAL-inside调用alist的每个乐趣,如果没有EVAL也不可能,那么我想知道。)

在公共Lisp中,这是由
PROGV
-变量的动态绑定提供的,给定变量的符号


GNU Emacs在其公共Lisp仿真中应该有
PROGV

在公共Lisp中,这是由
PROGV
-给定变量符号的变量动态绑定提供的


GNU Emacs在其公共Lisp仿真中应该有
PROGV

您可以使用
letf
cl-letf
在最近的Emacs中)。它绑定像
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)))))

您可以使用
letf
cl-letf
在最近的Emacs中)。它绑定像
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)))))
这就是您所需要的--不需要
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)
或者,如果您真的想看到
绑定,出于某种原因,让
绑定:

(defun call-each-fun-of-alist (alist)
  (dolist (e  alist)
    (eval `(let ((,(car e)  (read-from-minibuffer "value: ")))
             (funcall (cdr e))))))
这就是您所需要的--不需要
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)
或者,如果您真的想看到
绑定,出于某种原因,让
绑定:

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