代码之家  ›  专栏  ›  技术社区  ›  seth

使用带引号的符号调用defmacro

  •  2
  • seth  · 技术社区  · 15 年前

    我有这个数据结构(基本上):

    (setq ssm-list '(tasklist
      ((id . "10525295")
       (name . "Inbox")
       (sort_order . "0"))))
    

    这适用于获取名称:

    (defun ssm-list-get-prop (list prop)
      (cdr (assoc prop (car (cdr list)))))
    
    (ssm-list-get-prop slack-one-list 'name)
    

    我想创建一个宏,该宏将用名称创建一个defun ssm-list-name (或) ssm-list-id )因为列表中实际上有更多的属性。

    所以我试了一下:

    (defmacro ssm-list-prop-defun (field)
      `(defun ,(intern (concat "ssm-list-" field))
          (one-list)
          (cdr (assoc ,field (car (cdr one-list))))))
    
    (ssm-list-prop-defun 'name)
    (ssm-list-prop-defun 'id)
    

    但是最后两个电话都失败了 (wrong-type-argument characterp quote) 我试着把 symbol-name 在宏中,但这没有帮助。

    有办法做到这一点吗?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Trey Jackson    15 年前

    你非常接近,小的编辑会给你一个有效的解决方案。问题是你在混合符号和字符串。这将起作用:

    (defmacro ssm-list-prop-defun (field)
                       ;; note that concat operates on strings
      `(defun ,(intern (concat "ssm-list-" field))
         (one-list)
              ;; note that you need a symbol here, so quote the 
              ;; result of the call to intern
              ;; and, if you're always using symbols, 
              ;; might as well use assq
         (cdr (assq ',(intern field) (car (cdr one-list))))))
    
    ;; pass in a string
    (ssm-list-prop-defun "name")
    

    下面是使用符号的变体:

    ;; variant that works off a symbol
    (defmacro ssm-list-prop-defun (field)
      `(defun ,(intern (concat "ssm-list-" (symbol-name field)))
         (one-list)
         (cdr (assq ',field (car (cdr one-list))))))
    
    (ssm-list-prop-defun name)
    
        2
  •  0
  •   offby1    15 年前

    我想你想看看 defstruct 在CL包中: (info "(cl) Structures") (或) http://www.gnu.org/software/emacs/manual/html_node/cl/Structures.html#Structures )