emacs - Emacs Lisp 宏不展开 Alist
问题描述
这是我的宏,它应该做的是用来自body
的let
绑定包装一个vars-alist
(defmacro with-vars-alist (vars-alist &rest body)
`(let (,@(mapcar (lambda (cell) (list (car cell) (cdr cell))) vars-alist))
,@body))
当我查看它扩展到使用以下代码时
(defvar my-vars-alist '((var1 . "var1")
(var2 . "var2")))
(macroexpand-1 (with-vars-alist my-vars-alist `(concat ,var1 ,var2)))
我收到一个错误cons: Wrong type argument: sequencep, my-vars-alist
但是检查它(sequencep my-vars-alist)
返回t
。
该错误可能有一些简单的解决方案,但我无法找到它。
解决方案
请记住,宏的参数是un-evaluated,这意味着当您my-vars-alist
作为参数传递时,它会逐字作为符号 my-vars-alist
传递。
因此,在宏扩展期间,vars-alist
评估为符号my-vars-alist
而不是列表((var1 . "var1") (var2 . "var2"))
。
所以错误不是抱怨变量 my-vars-alist
不包含序列作为其值,而是符号 本身my-vars-alist
不是序列(这是正确的——它是一个符号)。
检查它
(sequencep my-vars-alist)
返回t
。
这也是正确的,因为my-vars-alist
它的值被评估为变量((var1 . "var1") (var2 . "var2"))
所以你需要eval
那个论点。例如:
,@(mapcar (lambda (cell) (list (car cell) (cdr cell)))
(eval vars-alist))
由于vars-alist
已经对符号进行了评估my-vars-alist
,因此这种更改意味着我们将该符号传递my-vars-alist
给eval
,后者将其作为变量进行评估以获取 所需的列表mapcar
。
您可能还想引用您传递给macroexpand-1
(或使用M-x pp-macroexpand-last-sexp
)的表单。
推荐阅读
- c# - 如何删除/释放分配给 NLog 记录器的内存
- java - 引物方法 Big-O 复杂度
- vue.js - 测试使用 cytoscape.js 的 Vue 组件?
- reactjs - Redux 状态结构
- css - CSS 列填充自动忽略打印的分页符
- javascript - 如果 HTML 文本超过一定长度并且 HTML 标记已关闭,则显示“阅读更多”链接
- c++ - 使用 Bazel 生成 QT 资源文件
- javascript - 如何合并两个大小相同的不同对象数组?
- c++ - cout fails to give output probably due to inline assembly
- python-3.x - ansible 无法验证目标目录