dispatcher
私は、3つの関連付けられた関数get-dispatcher
で名前付きset-dispatcher
を作成し、ディスパッチャーを操作するマクロを作成しましたcall-dispatcher
(ディスパッチ関数を取得し、追加するか、呼び出します)。それはすべてうまくいきます!ただし、関連する関数名の作成を自動化したいので、マクロのこれらすべての内部let
構造を単純な構築関数を定義する に入れています。以下のコードでは、get-
関数の名前のみがそのオートメーションで構築されていることに注意してください。set-
and onesのcall-
名前の作成には、まだその手動の匂いがします。
(defmacro create-dispatcher [name]
;creates a set of dispatching functions tagged
`(do
;define dispatcher
(def ~(symbol name) ~(atom {}))
(let
[name-w-prefix (fn [x] (~(symbol (str x "-" name))))]
; -- define getter
(defn (name-w-prefix "get")
"get-dispatcher [tag]: get a dispatcher fn by tag"
(~'[] (println "no tag is provided for '" ~(str name) "' dispatcher"))
(~'[tag]
(do
(println "dispatcher '" ~(str name) "' called with '" ~'tag "' tag")
; return the tagged dispatcher
( (keyword ~'tag) @~(symbol name) )))
)
; -- define caller
(defn ~(symbol (str "call-" name))
"get-dispatcher [tag & args]: call a dispatcher fn by tag and apply to the args"
~'[tag & args]
(apply (~(symbol (str "get-" name)) ~'tag) ~'args)
)
; -- define setter
(defn ~(symbol (str "set-" name))
~'[tag fn]
"add-dispatcher [tag fn]: add a dispatcher fn associated with the tag"
(swap! ~(symbol name) assoc (keyword ~'tag) ~'fn)
)
)
; -- report
(println "created dispatcher set for '" ~(str name) "' ok!")
))
ただし、問題があります。ステートメント バインドname-w-prefix
内でエラーが発生します。let
どうすれば修正できますか?
(また、私は初心者であり、Clojureで書いたのはほとんど最初のことなので、改善に関するアドバイスは大歓迎です)