Вопрос

Я думал, что опубликую это, поскольку у меня получилось работать наугад, без реального понимания того, что происходит, и я подумал, что было бы полезно, если бы кто-нибудь объяснил это.

Я понимаю, как получить доступ к элементу карты:params в обработчике Compojure:

(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_arg и ip это имена переменных, к которым я хочу привязать значения, но приведенная выше карта не является допустимой картой Clojure.Как это работает?

Я также понимаю, что это оценивается по карте кольцевого запроса (которая каким-то образом предоставляется defroutes макрос) но приведенное выше выражение не является функцией или определением макроса, так как же оно может "существовать" как допустимое выражение в моем коде?Существует ли какая-то приостановка действия обычных правил для аргументов макросов?Я не смог найти определение синтаксиса деструктурирующих форм, понятное этому не-лисперу.

Это было полезно?

Решение

Карта - это действительная деструктурная карта. В любом месте, где вы связываете имена, вы можете использовать разрушимость. Вы могли бы сделать то же самое в 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 - названные аргументы

Есть много в блоге, демонстрирующих разрушимость, в том числе это один. Я не уверен, какой из них будет каноническое место для участия.

Я не притворяюсь, что знаешь, что именно компонент делает с этой картой под капотом, но я предполагаю, что это бросает его в пусть или что-то подобное, как я продемонстрировал выше. 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 и отсроченной оценки.

Другие советы

Разрушение происходит внутри формы привязки, и для деструктурирования карты привязываемый параметр находится слева, а ключ - справа:

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

Compojure создает форму привязки за кулисами, так что форма деструктурирования карты, которую вы использовали выше, фактически превращается во что-то вроде:

(let [{{some_arg "some_arg"} :params}  request]
  ...)

Где request является неявно предоставленной картой.

Векторная версия (например,, [some_arg]), является альтернативой, которая просто противопоставляет :params карта, содержащаяся в запросе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top