2014-04-05 22 views
2

我想将可选的文档字符串添加到我的def*宏。例如:将可选的文档字符串添加到def *宏

(defmacro defhtml 
    "Macro to avoid backtick unquote[splicing] in html vectors. 
    TODO: Add optional docstring." 
    [name args & body] 
    `(defn ~name ~args (html [email protected]))) 

;; Working defhtml 
(defhtml include-css [href] 
    [:link {:href href :rel "stylesheet"}]) 

我想:

(defhtml include-css 
    "My optional docstring here." 
    [:link {:href href :rel "stylesheet"}]) 

我想应该有一些常见的成语这一点。

+0

我想你想添加可选的文档字符串*您高清*宏*的调用。 – Thumbnail

回答

5

你需要决定你的宏的第二个参数是否是文档字符串(你可以测试它是否是一个字符串)。 Clojure宏是Clojure,因此您可以在传递给您想要的宏的表单上执行任何逻辑或操作。这应该是接近,如果不完全是你后:

(defmacro defhtml [name & args] 
    (cond 
    ;; doc-string? 
    (string? (first args)) 
    (let [[doc-string args-list & body] args] 
     `(defn ~name ~doc-string ~args-list (html [email protected]))) 

    :no-doc-string 
    (let [[args-list & body] args] 
     `(defn ~name ~(format "HTML Generator %s" name) ~args-list (html [email protected]))))) 

这应该产生你的宏展开后:

(defhtml include-css [href] 
    [:link {:href href :rel "stylesheet"}]) 

生产:

(defn include-css 
    "HTML Generator include-css" 
    [href] 
    (html [:link {:href href, :rel "stylesheet"}])) 

同时:

(defhtml include-css 
    "Standard css includes fory my site" 
    [href] 
    [:link {:href href :rel "stylesheet"}]) 

产生:

(defn include-css 
    "Standard css includes fory my site" 
    [href] 
    (html [:link {:href href, :rel "stylesheet"}])) 
2

defndefmacro已经支持可选文档字符串,因此,如果您def*宏展开到其中的一个电话,你可能不需要在你自己的代码中的任何string?检查。这是defhtml的情况下,因此可以实现:

;; also adding an optional attribute map parameter, because why not? 
(defmacro defhtml [name doc? attr-map? params & body] 
    `(defn ~name ~doc? ~attr-map? ~params (html [email protected]))) 

;; equivalent, perhaps prettier: 
(defmacro defhtml [name doc? attr-map? params & body] 
    `(defn [email protected][name doc? attr-map? params] (html [email protected]))) 
+0

'def'也接受一个可选的docstring参数,但是在编写可选文档字符串和* body *(任意多个表达式)并直接扩展到'def'的宏中没有太大的帮助。 –

相关问题