2

我有一个已知变量列表和带有 nil 参数列表的相应函数,在它内部它使用已知的非参数(或全局)变量。

例如

(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

(不一定,但没有在 call-each-fun-of-alist 中调用 EVAL,如果没有 EVAL 是不可能的,我也想知道它。)

4

3 回答 3

3

你可以用letfcl-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)))))
于 2013-04-13T17:57:09.487 回答
1

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

GNU Emacs 应该PROGV在其 Common Lisp 仿真中。

于 2013-04-13T17:50:16.890 回答
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))))))
于 2013-10-26T18:23:49.877 回答