我有一个宏defprinter
,我可以在其中定义一些函数:基于解构+在打印该变量时获取一个值。Clojure宏:只有在定义符号时才执行动作
这看起来像:
(defmacro defprinter [name pattern]
(list 'defn name [pattern] '(prn to-print)))
所以我可以这样做(defprinter print-lemons {to-print :lemons})
然后(print-lemons {:lemons "lemons"})
它会打印出正确的事情(我可以在第一个参数的任何一种解构的定义打印机)。
但现在我想给这个函数的也许知道如何与彩色打印为好,如,如果符号color
定义,它应该做(prn color "-colored " to-print)
,但其他人只是(prn color)
的选项。
因此,由(defprinter print-lemons {to-print :lemons})
生成的函数应该与上面相同,而(defprinter print-lemons {to-print :lemons, color :color})
将编写一个执行彩色版本的函数。
此外,我想要同样的效果,如果我做 (let [color "black"] (defprinter print-lemons {to-print :lemons}))
或(def color "black") (defprinter print-lemons {to-print :lemons})
。
这可能吗?
我试着写了以下的方法:
(defmacro defprinter [name pattern]
(list 'defn name [pattern]
'(try (eval '(prn (str color "-colored " to-print)))
(catch java.lang.RuntimeException _
(prn to-print)))))
在我的理解功能的宏将写会尽量EVAL在运行时的表情,失败,一个RuntimeException如果color
没有定义,然后执行(prn to-print)。即使它会在运行时检查color
的存在,to-print
(它始终需要存在该函数)将在宏扩展时在编译时检查。
但是,这里发生的是,即使在定义了color
(即使我只在eval语句中只保留to-print
,它也找不到它,但catch中的子句正常工作),我总是得到一个RuntimeException。似乎这个符号没有像我在eval期间所预期的那样得到解决,但我想不出有任何其他方法可以实现这一点。
有什么建议吗?