【问题标题】:Use a string variable as macro argument使用字符串变量作为宏参数
【发布时间】:2017-02-02 02:52:25
【问题描述】:

我想要这个代码:

(setq name "foobar")
(defun (intern name) ())

做同样的事情:

(defun foobar ())

我试过这个(来自This question):

(defmacro make-my-function (name)
(list 'defun
(intern (format "my-%s-function" name)) ()
    (list 'interactive)
    '(message "It's work !")))

但我得到了一个名为 my-name-function 的函数,但我想要 my-foobar-function。我的目标是从键盘映射列表中定义未成年人模式。

谢谢

【问题讨论】:

    标签: emacs lisp-macros


    【解决方案1】:

    您的宏运行良好。你是如何尝试调用它的?您应该像这样调用:(make-my-function foo)。然后M-: (symbol-function 'my-foo-function)给你看函数定义:

    (lambda nil
      (interactive)
      (message "It's work !"))
    

    您在定义宏之前的初始尝试不起作用的原因是 defun 是一个宏 - 它不会评估其参数。所以(defun (intern name) ()) 在语法上是不正确的:defun 需要一个符号作为它的第一个参数,而(intern name) 是一个列表,而不是一个符号。


    在您发表评论后更新 -

    你的问题很不清楚。现在听起来你想在你有一个 variable my-foo-function 的上下文中调用(make-my-function foo),它的值是一个字符串。

    如果是这样,那么使用这个:

    (defmacro make-my-function (name)
      (list 'defun
            (intern (symbol-value (intern (format "my-%s-function" name))))
            ()
            (list 'interactive)
            '(message "It's work !")))
    
    (setq my-foo-function "toto")
    (make-my-function foo)
    

    我无法想象这样的用例,但我怀疑这也不是您想要做的。您似乎没有很好地指定所需的行为是什么。

    【讨论】:

    • 我想你误解了:我想像这样调用我的宏:(make-my-function a-variable-contain-the-name-as-string)而不是这样:(make-我的功能 foobar)
    • 我的主要问题是将字符串转换为符号
    • 一个宏不会计算它的参数,除非你告诉它。如果您希望(make-my-function a-variable-contain-the-name-as-string) 评估a-variable-contain-the-name-as-string,那么宏主体需要显式评估该参数。
    【解决方案2】:

    我无法使用您的 make-my-function 宏重新创建您的问题,但请尝试使用 backquote

    (defmacro make-my-function (name)
      `(defun ,(intern (format "my-%s-function" name)) ()
        'interactive
        '(message "It works!")))
    

    【讨论】:

      猜你喜欢
      • 2020-10-31
      • 2012-05-17
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 2011-10-22
      • 1970-01-01
      相关资源
      最近更新 更多