我正试图通过herbstclient从Emacs拨打bash程序process-lines。我创建了一个宏hc调用,它实际上调用了由函数hc调用的herbstclient,它应该通过stringify-numbers将其数字参数转换为字符串。
毋庸置疑,它不起作用。用“keybind”“mod4-Shift-r”“reload”调用hc会出错:
*** Eval error *** Wrong type argument: listp, stringified-args
我尝试在hc上使用edebug,输出建议stringify-numbers正常工作。该函数在hc调用时立即出错。然而,当我跑步时:
(hc-call ("keybind" "Mod4-Shift-r" "reload"))
它按预期工作。然后我尝试了:
(setq sargs (list "keybind" "Mod4-Shift-r" "reload"))
(hc-call sargs)
我得到了同样的错误。我不知道如何进一步调试。以下是所有代码:
(defmacro hc-call (args)
"Call herbstclient to with the given arguments."
`(process-lines "herbstclient" ,@args))
(defun stringify-numbers (args)
"Take a list of random arguments with a mix of numbers and
strings and convert just the numbers to strings."
(let (stringified-args)
(dolist (arg args)
(if (numberp arg)
(setq stringified-args (cons (number-to-string arg) stringified-args))
(setq stringified-args (cons arg stringified-args))))
(nreverse stringified-args)))
(defun hc (&rest args)
"Pass arguments to herbstclient in a bash process."
(let ((stringified-args (stringify-numbers args)))
(hc-call stringified-args)))
为什么会抱怨stringified-args不是列表?
答案 0 :(得分:2)
你的hc-call
应该是一个功能,与
(defun hc-call (args)
"Call herbstclient to with the given arguments."
(apply #'process-lines "herbstclient" args))
是的,顺便说一句,我在这里:
(if (numberp arg)
(setq stringified-args (cons (number-to-string arg) stringified-args))
(setq stringified-args (cons arg stringified-args))))
写得更好
(setq stringified-args (cons (if (numberp arg) (number-to-string arg) arg) stringified-args))))
或
(push (if (numberp arg) (number-to-string arg) arg) stringified-args)))
答案 1 :(得分:1)
与大多数表达式不同,宏参数传递未评估。
这就是(hc-call ("keybind" "Mod4-Shift-r" "reload"))
不会导致错误的原因!
因此,(hc-call sargs)
将符号sargs
传递给宏,而不是传递给它的列表。
如果您希望宏以这种方式处理变量,您可以将,@args
更改为,@(eval args)
,或者以任何方式有条件地处理args
,具体取决于它的结果实际上是。