Uso simple de request.el


9

Mi pregunta embarazosamente fácil es la siguiente:

¿Por qué funciona el siguiente código?

(require 'request)

(defun geocoder ()
  (request
   "http://rpc.geocoder.us/service/csv"
   ;;; **Hardcoded parameter!**
   :params '(("address" . "1600 Pennsylvania Ave, Washington DC"))
   :parser 'buffer-string
   :success (function*
             (lambda (&key data &allow-other-keys)
                (when data
                (with-current-buffer (get-buffer-create "*request demo*")
                  (erase-buffer)
                  (insert data)
                  (pop-to-buffer (current-buffer))))))
   :error
   (function* (lambda (&key error-thrown &allow-other-keys&rest _)
                (message "Got error: %S" error-thrown)))
   ))

(geocoder)

Mientras que este no?

(require 'request)

(defun geocoder (address) ;; adding a parameter!
  (request
   "http://rpc.geocoder.us/service/csv"
   :params '(("address" . address))
   :parser 'buffer-string
   :success (function*
             (lambda (&key data &allow-other-keys)
                (when data
                (with-current-buffer (get-buffer-create "*request demo*")
                  (erase-buffer)
                  (insert data)
                  (pop-to-buffer (current-buffer))))))
   :error
   (function* (lambda (&key error-thrown &allow-other-keys&rest _)
                (message "Got error: %S" error-thrown)))
   ))

;;; Now with parameter!
(geocoder "1600 Pennsylvania Ave, Washington DC")

¿Cómo debo enviar un parámetro para solicitar?

Respuestas:


11

Esto se debe a que '(("address" . address))se cita (es decir, con el prefijo del 'operador), lo que significa que lo que está dentro no se evalúa. Por lo requesttanto, la función se llama con un argumento que es el address símbolo no evaluado (mientras que en su primera implementación, la requestfunción obtiene una cadena literal, que no necesita evaluarse primero).

Puedes arreglar esto de 2 maneras:

1) citando el argumento, lo que le permite obtener principalmente el mismo comportamiento pero especificar partes que aún deben evaluarse:

`(("address" . ,address))

Tenga en cuenta que la comilla simple ( ') ha sido reemplazada por una comilla invertida ( `), y ,se agregó un marcador especial antes addresspara indicar que debe evaluarse y sustituirse con su valor.

2) (según el comentario de @ JordonBiondo) construyendo la estructura explícitamente usando primitivas como listo cons. En su caso, esto se haría así:

(list (cons "address" address))

donde, de nuevo, "address"es un literal de cadena (que se evalúa a sí mismo), y addressse evalúa ya que es el argumento en una llamada a la función.


Gracias por la explicación. Está mejorando, pero ahora aparece "Argumento de tipo incorrecto: integerp, \," :(
baol

¡Ah, está bien: gnu.org/software/emacs/manual/html_node/elisp/Quoting.html que es una cita inversa!
baol

1
Agregué enlaces a partes relevantes del manual para hacerlo más claro. Y también mencioné explícitamente el presupuesto ya que, como era de esperar, no era tan obvio a primera vista ...
François Févotte

66
alternativamente, podrías escribir eso como (list (cons "address" address))si no quisieras usar backticks
Jordon Biondo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.