【问题标题】:Message in macro printed twice宏中的消息打印两次
【发布时间】:2016-03-23 04:45:40
【问题描述】:

我编写了一个函数,它可以接受任何种类、任意数量的参数,以便它可以打印参数的名称和值。该功能按预期工作。但我不喜欢函数调用要求我传递像(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.

有什么问题?

【问题讨论】:

    标签: macros elisp message


    【解决方案1】:

    您出于错误的原因使用宏。

    宏不仅仅是避免代码中出现多余字符的噱头。

    宏对代码进行操作。 IOW,您编写的代码在编译时(或宏扩展时,如果未编译)执行,然后使用结果而不是宏形式。

    所以,你的宏的符号(更一般地说,sexp)部分应该是这样的

    `(message "symbol: %s, value: %s" ',arg ,arg)
    

    如果您不了解上述内容,请阅读backquote

    但是,让我再说一遍:宏是“高级材料”,在您更熟悉 Lisp 之前,您可能更愿意避免使用它们。

    【讨论】:

    • 我总是与宏混淆。我尝试编译代码并给出了预期的结果。使用宏生成结果的缺点是什么。虽然这不是直接回答问题,但它指出了另一个问题。所以你得到了我的 +1 奖励。
    【解决方案2】:

    我认为消息 [2 times] 在您的输出中指的是一个额外的换行符。

    这种行为可以通过评估来重现

    (progn
      (message "HelloWorld")
      (message "\n"))
    

    在 *scratch* 中。 *messages* 中的输出是

    HelloWorld
    [2 times]
    "
    "
    

    我想知道这种行为是否是故意的。

    也许我确实误解了你的问题,因为我的回答与宏无关。

    【讨论】:

    • 这才是[2 times]产生的真正原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多