我有一個宏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期間所預期的那樣得到解決,但我想不出有任何其他方法可以實現這一點。
有什麼建議嗎?