Pregunta

Me pensé que había puesto esto como lo tengo al trabajo a través de conjeturas sin una comprensión real de lo que está pasando y pensé que podría ser útil si alguien lo explicó.

entiendo cómo llegar a un elemento de la: params mapa en un manejador Compojure:

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

o

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

A pesar de que no entiendo completamente lo que la parte {some_arg "some_arg"} está haciendo: (

Yo también quería tener acceso a la parte :remote-addr de la solicitud, así como some_arg. Y terminé con

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

Por lo tanto, entiendo que las cuerdas no cotizados some_arg y ip son los nombres de las variables a las que desea que los valores ligados pero el mapa de arriba no es un mapa Clojure válida. ¿Cómo funciona?

También consigo que esta se evalúa la solicitud mapa anillo (que se suministra de alguna manera por la macro defroutes), pero la expresión anterior no es una función o macro definición así que ¿cómo puede él 'existir' como una expresión válida en mi ¿código? ¿Hay algún tipo de suspensión de las reglas normales de argumentos de la macro? He sido incapaz de encontrar una definición de la sintaxis de la desestructuración de formas comprensibles para este no Lisp'er.

¿Fue útil?

Solución

El mapa es un mapa desestructuración válida. En cualquier lugar donde se enlaza nombres, puede utilizar desestructuración. Se podría hacer lo mismo en un let, como esto:

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"]

Me escribió un post sobre un mapa desestructuración en el contexto de argumentos con nombre, pero se aplica aquí. Usted puede encontrar esto útil: Clojure - argumentos con nombre

Hay mucho de Publicaciones demostrando desestructuración, incluyendo éste . No estoy seguro de cuál sería un lugar canónica que aprender.

Yo no pretendo saber qué es exactamente lo que hace con compojure mapa bajo el capó, pero supongo que lo tira en un let o algo similar como lo ha demostrado más arriba. GET es una macro, por lo que no tiene que evaluar el mapa se le pasa, por lo que no se obtendría un error a menos que lo evaluó.

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)

Bajo el capó, la magia sucede a ese mapa y se pasa a una función llamada desestructuración que hace la magia desestructuración.

En realidad no hay nada especial que hacer aquí que no sea normal, macro / foo forma especial y la evaluación retrasada.

Otros consejos

Destructing tiene lugar dentro de una forma de unión, y para desestructurar el mapa var en obligarse está a la izquierda, y la clave está en la derecha:

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

Compojure está haciendo una forma de unión entre bastidores, de manera que forman un mapa desestructuración que estaba utilizando anteriormente se convirtió efectivamente en algo como:

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

Cuando request es un mapa que aparece de forma implícita.

La versión vector (por ejemplo, [some_arg]), es una alternativa que sólo se une contra el mapa :params contenidas en la solicitud.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top