【发布时间】:2017-06-01 19:19:51
【问题描述】:
我有一个宏 defprinter,我可以在其中定义以下函数:基于解构获取 dic 中的值 + 打印该变量。
这看起来像:
(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)))))
据我了解,宏将编写的函数将尝试在运行时评估表达式,如果未定义 color,则失败并出现 RuntimeException,然后执行 (prn to-print)。即使它会在运行时检查color 是否存在,但to-print(该函数始终需要存在)将在宏展开时在编译时进行检查。
但是这里发生的情况是我总是得到一个 RuntimeException,即使定义了color(即使我在 eval 语句中只留下to-print,它也找不到它,但是 catch 中的子句可以正常工作)。似乎符号没有像我在评估期间所期望的那样被解析,但我想不出任何其他方法来实现这一点。
有什么建议吗?
【问题讨论】: