私はマクロを持っていますdefprinter
ここで関数を定義することができます。Clojureマクロ:シンボルが定義されている場合にのみアクションを実行します
これは次のようになります。だから私は(defprinter print-lemons {to-print :lemons})
ような何かをしてから(print-lemons {:lemons "lemons"})
、それが正しい事を出力します(と私は、最初の引数に構造化代入のあらゆる種類のプリンタを定義することができます)することができます
(defmacro defprinter [name pattern]
(list 'defn name [pattern] '(prn to-print)))
。
しかし、今私は多分、同様の色で印刷する方法を知っている機能のオプションを提供したい、などの記号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})
と同じ効果が欲しいです。
これは可能ですか?
私はそれを次のように書いて試してみた:color
が定義されていない場合はRuntimeExceptionで失敗し、その後、私の理解マクロは、実行時に式をevalにしようとする書き込みをする関数で
(defmacro defprinter [name pattern]
(list 'defn name [pattern]
'(try (eval '(prn (str color "-colored " to-print)))
(catch java.lang.RuntimeException _
(prn to-print)))))
を(prn to-print)を実行します。実行時にcolor
の存在をチェックしても、マクロが展開されるときにコンパイル時にto-print
(常にその関数のために存在する必要がある)がチェックされます。
しかし、color
が定義されていても、私はいつもRuntimeExceptionを取得します(たとえ私がeval文にto-print
だけ残しても、それを見つけることはできませんが、catchの節はうまく動作します)。私がevalの間に期待していたように、シンボルが解決されていないように見えますが、これを達成する他の方法は考えられません。
提案がありますか?