6

私は最近 Compojure で遊んでいて、小さな基本的な webapp を手に入れました。私の HTML テンプレートには Enlive を使用しており、すべての単純な静的ページを保持する名前空間があります。これらのページの defroute 呼び出しは次のようになります。

(defroutes public-routes
  (GET "/" []
    (info/index-template))
  (GET "/about" []
    (info/about-template))
  (GET "/contact" []
    (info/contact-template)))

私は実際にはそれよりもいくつか持っていますが、それは私が何をしているかのアイデアを与えるはずです.

さて、それは本当に私の側の繰り返しの束だと思ったので、次のことを試してみようと思いました:

(defroutes info-routes
  (map #(GET (str "/" %) [] (ns-resolve 'webapp.pages.info
                                        (symbol (str % "-template"))))
       '("about" "contact")))

もちろん、マップは関数の本体 (?) ではなく遅延シーケンスを返すため、これは機能しません。このアイデアを機能させるために私が何をする必要があるかを誰かが知っていますか?

それとも、同じことを繰り返すのを減らすために、まったく別のアプローチを使用する必要がありますか?

4

2 に答える 2

5

routesdefroutesで使用される関数はいつでも使用できます。

(defroutes info-routes
  (apply routes
    (map #(GET (str "/" %) [] 
               (ns-resolve 'webapp.pages.info
                           (symbol (str % "-template"))))
         '("about" "contact"))))

しかし、それはまだかなり退屈です、それをスパイスしましょう!;-)

(defn templates-for [& nss]
  (->> nss
       (map ns-publics)
       (apply concat)
       (filter #(->> % first str
                     (re-seq #"-template$")))
       (map second)))

(defn template-uri [template]
  (->> template meta :name name
       (re-seq  #"(.*)-template$")
       first second (str "/")))

(defn template->route [template]
  (GET (template-uri template) [] template))

(defroutes public-routes
  (GET "/" [] "foo")
  (apply routes (map template->route
                     (templates-for 'webapp.pages.info))))

このコードを使用すると、templates-for関数は指定された名前空間で「-template」で終わる関数を探し、それらを使用して適切なルートを記述します。マクロを使用していないが、多くの構成を使用している様子を見てください。

于 2011-04-28T17:30:10.627 に答える
1

defroutesはマクロなので、残念ながら map などの関数に渡すことはできません。defroutes の呼び出しに展開されるマクロを作成する必要があります。または、展開先の関数を見て、それらを直接呼び出します。

このような defroutes の呼び出し内でルートのリストを作成することはできません

(defroutes public-routes
  (make-list-of-routes)

ルートのリストに展開されます。

(defroutes public-routes
  ( (GET "/" [] (info/index-template)) 
    (GET "/about" [] (info/about-template))
    (GET "/contact" [] (info/contact-template))) )

defroutes通常の関数でこれを解決する場合apply

(apply defroutes (conj 'public-routes (make-list-of-routes)))

はマクロであるためdefroutes、適用が実行される前に完全に終了し、結果はあまり意味がありません。マクロを関数として構成することはできません。マクロは clojure (または私が知っているすべての Lisp) の第一級市民ではありません。一部の Clojurians (通常は私ではありません) が「マクロは悪」と言うとき、彼らはしばしば、何かがマクロであるという事実に遭遇するこのような状況について考えます。作成しようとしてもできません。

解決策は、defroutes マクロを使用せず、routes 関数を直接呼び出すことです。

于 2011-04-28T00:44:24.433 に答える