6

何が起こっているのかを実際に理解せずに当て推量で動作するようになったので、これを投稿すると思いました。誰かが説明してくれれば役立つかもしれないと思いました。

Compojureハンドラーで:paramsマップの要素を取得する方法を理解しています。

(GET "/something" [some_arg] "this is the response body")

また

(GET "/something" {{some_arg "some_arg"} :params} "this is the response body")

私はその部分が何をしているのか完全には理解していませんが{some_arg "some_arg"}:(

:remote-addrまた、リクエストの一部にもアクセスしたかったのsome_argです。そして、私は

(GET "/something" {{some_arg "some_arg"} :params ip :remote-addr}
    (do-something-with some_arg ip))

したがって、引用符で囲まれていない文字列some_argipは、値をバインドする変数の名前ですが、上のマップは有効なClojureマップではありません。それはどのように機能しますか?

また、これはRingリクエストマップ(defroutesマクロによって提供される)に対して評価されることもわかりますが、上記の式は関数またはマクロ定義ではないため、コードに有効な式として「存在する」にはどうすればよいですか?マクロ引数の通常のルールのある種の一時停止はありますか?私は、この非Lisp'erに理解できる破壊フォームの構文の定義を見つけることができませんでした。

4

2 に答える 2

3

マップは有効な破壊マップです。名前をバインドする場所であればどこでも、destructuringを使用できます。次のように、で同じことを行うことができますlet

user=> (let [{{some-arg "some_arg"} :params ip :remote-addr} {:remote-addr "127.0.0.1" :params {"some_arg" "some_value"}}] [ip some-arg])
["127.0.0.1" "some_value"]

名前付き引数のコンテキストでマップの破棄について投稿しましたが、ここに適用されます。これは便利だと思うかもしれません:Clojure-名前付き引数

これを含め、破壊を示すブログ投稿がたくさんあります。どちらが標準的な場所から学ぶことができるかわかりません。

ボンネットの下にあるそのマップでcompojureが正確に何をするのかを知っているふりはしませんが、上で示したように、それがletまたは同様の何かにそれを投げ込むと思います。GETはマクロであるため、渡したマップを評価する必要はありません。そのため、GETを評価しない限り、エラーは発生しません。

user=> (defmacro blah [m])
#'user/blah
user=> (blah {a "b" c "d"})
nil
user=> (defn blah [m])
#'user/blah
user=> (blah {a "b" c "d"})
java.lang.Exception: Unable to resolve symbol: a in this context (NO_SOURCE_FILE:9)

内部では、魔法がそのマップに発生し、破壊魔法を実行する破壊と呼ばれる関数に渡されます。

通常のマクロ/特殊形式のfooと遅延評価以外に、ここで特別なことは何も起こっていません。

于 2010-11-03T16:43:14.913 に答える
1

破棄はバインディングフォーム内で行われ、マップの破棄では、バインドされる変数が左側にあり、キーが右側にあります。

user =>(let [{a:foo} {:foo:bar}]
user = * a)
:バー

Compojureは舞台裏でバインディングフォームを実行しているため、上記で使用していたマップ破壊フォームは効果的に次のようなものに変換されます。

([{{some_arg "some_arg"}:params}リクエスト]
  ...)

request暗黙的に提供されるマップはどこにありますか。

ベクトルバージョン(たとえば、 )は、リクエストに含まれるマップ[some_arg]に対してバインドするだけの代替手段です。:params

于 2010-11-03T16:44:42.130 に答える