2016-12-01 63 views
1

我与clojure.spec尝试,我想我会写一个宏来节省一些繁琐的打字:-)clojure:我如何将一个名称空间作为宏参数传递?

我试图做到这一点:

(defmacro nup 
    [pns pname punit] 
    `(s/def :~pns/name (s/and #(string? %) #(= % ~pname))) 
    `(s/def :~pns/unit (s/and #(string? %) #(= % ~punit)))) 

我试过几个版本,但我不能使名称空间替换工作。有任何想法吗?不用说,宏不是我的强项。

+0

你不需要任何一个宏,只需在函数中执行's/def'即可。 – ClojureMostly

回答

1

你去那里:

(defmacro nup 
    [pns pname punit] 
    `(do 
    (s/def ~(keyword (str pns) "name") (s/and #(string? %) #(= % ~pname))) 
    (s/def ~(keyword (str pns) "unit") (s/and #(string? %) #(= % ~punit))))) 

(macroexpand-1 
    '(nup ab :foo :bar)) 

s/def只是登记在规范的注册表中的关键字。所以你根本不需要宏。只需使用一个功能,就容易得多。

相关问题