宏中的消息打印两次
Message in macro printed twice
我编写了一个函数,它可以接受任何类型、任意数量的参数,因此它可以打印参数的名称和值。该功能按预期工作。但我不喜欢函数调用要求我传递像这样 (my-message 'emacs-version 'emacs-copyright)
的引用值。我想简化为 (my-message emacs-version emacs-copyright)
。所以我用宏来重写函数。
(defmacro my-message (&rest args)
(if args
(progn
(message "This is the start of debug message.\n")
(dolist (arg args)
(cond
((stringp arg)
(message arg))
((numberp arg)
(message (number-to-string arg)))
((boundp arg)
(pp arg)
(message "")
(pp (symbol-value arg)))
((not (boundp arg))
(pp arg)
(message "Undefined")))
(message "\n"))
(message "This is the end of debug message."))
(message "This is a debug message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")))
但是,某些消息被打印了两次。
(my-message emacs-version emacs-copyright 12345 "HelloWorld" foobar)
This is the start of debug message.
emacs-version
"24.5.1"
[2 times]
emacs-copyright
"Copyright (C) 2015 Free Software Foundation, Inc."
[2 times]
12345
[2 times]
HelloWorld
[2 times]
foobar
Undefined
[2 times]
This is the end of debug message.
有什么问题?
您使用宏的原因不对。
宏不仅仅是避免代码中出现额外字符的噱头。
宏对代码进行操作。
IOW,您编写的代码在编译时(或宏扩展时,如果未编译)执行,然后使用结果而不是宏形式。
因此,您的宏的符号(更一般地说,sexp)部分应该如下所示
`(message "symbol: %s, value: %s" ',arg ,arg)
如果您不理解以上内容,请继续阅读 backquote。
但是,让我重复一遍:宏是 "advanced material",在您熟悉 Lisp 之前,您可能更愿意避免使用它们。
我觉得留言
[2 times]
在你的输出中指的是一个额外的换行符。
可以通过评估重现此行为
(progn
(message "HelloWorld")
(message "\n"))
在*scratch*。 *messages* 中的输出是
HelloWorld
[2 times]
"
"
我想知道这种行为是否是故意的。
也许我确实误解了你的问题,因为我的回答与宏无关。
我编写了一个函数,它可以接受任何类型、任意数量的参数,因此它可以打印参数的名称和值。该功能按预期工作。但我不喜欢函数调用要求我传递像这样 (my-message 'emacs-version 'emacs-copyright)
的引用值。我想简化为 (my-message emacs-version emacs-copyright)
。所以我用宏来重写函数。
(defmacro my-message (&rest args)
(if args
(progn
(message "This is the start of debug message.\n")
(dolist (arg args)
(cond
((stringp arg)
(message arg))
((numberp arg)
(message (number-to-string arg)))
((boundp arg)
(pp arg)
(message "")
(pp (symbol-value arg)))
((not (boundp arg))
(pp arg)
(message "Undefined")))
(message "\n"))
(message "This is the end of debug message."))
(message "This is a debug message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")))
但是,某些消息被打印了两次。
(my-message emacs-version emacs-copyright 12345 "HelloWorld" foobar)
This is the start of debug message.
emacs-version
"24.5.1"
[2 times]
emacs-copyright
"Copyright (C) 2015 Free Software Foundation, Inc."
[2 times]
12345
[2 times]
HelloWorld
[2 times]
foobar
Undefined
[2 times]
This is the end of debug message.
有什么问题?
您使用宏的原因不对。
宏不仅仅是避免代码中出现额外字符的噱头。
宏对代码进行操作。 IOW,您编写的代码在编译时(或宏扩展时,如果未编译)执行,然后使用结果而不是宏形式。
因此,您的宏的符号(更一般地说,sexp)部分应该如下所示
`(message "symbol: %s, value: %s" ',arg ,arg)
如果您不理解以上内容,请继续阅读 backquote。
但是,让我重复一遍:宏是 "advanced material",在您熟悉 Lisp 之前,您可能更愿意避免使用它们。
我觉得留言
[2 times]
在你的输出中指的是一个额外的换行符。
可以通过评估重现此行为
(progn
(message "HelloWorld")
(message "\n"))
在*scratch*。 *messages* 中的输出是
HelloWorld
[2 times]
"
"
我想知道这种行为是否是故意的。
也许我确实误解了你的问题,因为我的回答与宏无关。