3

ヒカップ データ構造を表すベクター ツリーをトラバースしたい:

[:div {:class "special"} [:btn-grp '("Hello" "Hi")]] 

次に、ベクトルのキーワードでディスパッチしたいのですが、キーワードにマルチメソッドが定義されている場合、別のベクトルのセットが返され、元のタグが置き換えられます。

たとえば、上記の構造は次のように変換されます。

[:div {:class "special"} [:div [:button "Hello"] [:button "Hi"]]]

カスタム マルチメソッドは、リスト ("hello" "hi") をパラメーターとして受け取ります。次に、ボタンを含む div を返します。

ベクトルをトラバースし、フォーム内の他のすべてをパラメーターとしてキーワードでディスパッチし、現在のフォームを返されたフォームに置き換える関数を作成するにはどうすればよいですか?

4

1 に答える 1

1
(ns customtags
  (:require [clojure.walk :as walk]))

(def customtags (atom {}))

(defn add-custom-tag [tag f]
  (swap! customtags assoc tag f))

(defn try-transform [[tag & params :as coll]]
  (if-let [f (get @customtags tag)]
    (apply f params)
    coll))

(defmacro defcustomtag [tag params & body]
  `(add-custom-tag ~tag (fn ~params ~@body)))

(defn apply-custom-tags [coll]
  (walk/prewalk
    (fn [x]
      (if (vector? x)
        (try-transform x)
        x)) coll))

それを使用して:

(require '[customtags :as ct])
(ct/defcustomtag :btn-grp [& coll] (into [:div] (map (fn [x] [:button x]) coll)))
(ct/defcustomtag :button [name] [:input {:type "button" :id name}])

(def data [:div {:class "special"} [:btn-grp "Hello" "Hi"]])

(ct/apply-custom-tags data)
[:div {:class "special"} [:div [:input {:type "button", :id "Hello"}] [:input {:type "button", :id "Hi"}]]]
于 2012-05-15T10:18:40.080 に答える