Почему слияние используется вместо простого слияния в Ring, Clojure?

Я новичок в Clojure и изучаю Clojure, читая хороший открытый исходный код. Поэтому я выбираю Ring и начинаю читать код, но застрял в функции assoc-query-params. (который находится в кольце. промежуточное ПО / params.clj)

И я не мог понять, почему используется «слияние». Может ли кто-нибудь помочь мне понять этот фрагмент кода?

(defn- assoc-query-params
  "Parse and assoc parameters from the query string with the request."
  [request encoding]

  ; I think (merge request (some-form)) is enough
  ; but the author used merge-with with merge function.

  (merge-with merge request
    (if-let [query-string (:query-string request)]
      (let [params (parse-params query-string encoding)]
        {:query-params params, :params params})
      {:query-params {}, :params {}})))

person popopome    schedule 21.08.2013    source источник


Ответы (1)


Вот описание функции merge: перефразировано, в нем говорится, что если ключ встречается более одного раза, чем будет выбрано значение на последней карте. В опубликованном вами примере это будет означать, что значения :query-params :params будут взяты как есть из хвоста функции, вместо того, чтобы объединять их с тем, что в запросе.

Посмотрим на пример:

(def m {:a {:a-key1 "value1"} :b {:b-key1 "value3"} :c {}})
(def m2 {:a {:a-key2 "value2"} :b {}})

(merge m m2)
;-> {:a {:a-key2 "value2"}, :b {}, :c {}}

(merge-with merge m m2)
;-> {:a {:a-key1 "value1", :a-key2 "value2"}, :b {:b-key1 "value3"} :c {}}

Итак, (merge-with merge ...) construct дает нам возможность объединять карты на карте. Вы можете посмотреть на это так: слияние сгруппирует все пары ключ / значение по ключу (:a :b :c в нашем примере) и применит слияние к их значениям.

{:a (merge {:a-key1 "value1"} {:a-key2 "value2"}) 
 :b (merge {:b-key1 "value3"} {})
 :c (merge {})}

Разобравшись с этим, я думаю, что первоначальное намерение автора assoc-query-params состоит в том, чтобы расширить :query-params и :params вместо их полной замены.

person Ivan Koblik    schedule 21.08.2013