Semplice utilizzo request.el


9

La mia domanda imbarazzante è la seguente:

Perché funziona il seguente codice:

(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)

Mentre questo 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")

Come devo inviare un parametro per richiedere?

Risposte:


11

Questo perché '(("address" . address))viene citato (ovvero prefissato 'dall'operatore), il che significa che ciò che è dentro non viene valutato. La requestfunzione viene quindi chiamata con un argomento che è il address simbolo non valutato (mentre nella tua prima implementazione, la requestfunzione ottiene una stringa letterale, che non ha bisogno di essere valutata prima).

Puoi risolverlo in 2 modi:

1) quasi citando l'argomento, che consente di ottenere principalmente lo stesso comportamento ma di specificare parti che devono ancora essere valutate:

`(("address" . ,address))

Si noti che la singola virgoletta ( ') è stata sostituita da un backquote ( `) e ,prima è stato aggiunto un marcatore speciale addressper indicare che deve essere valutato e sostituito con il suo valore.

2) (come da commento di @ JordonBiondo) costruendo esplicitamente la struttura usando primitivi come listo cons. Nel tuo caso, questo sarebbe fatto in questo modo:

(list (cons "address" address))

dove, di nuovo, "address"è una stringa letterale (che si valuta da sé) e addressviene valutata poiché è l'argomento in una chiamata di funzione.


Grazie per la spiegazione. Sta migliorando, ma ora ottengo "Argomento di tipo errato: integerp, \," :(
baol


1
Ho aggiunto collegamenti alle parti pertinenti del manuale per renderlo più chiaro. E ho anche menzionato esplicitamente il backquote poiché non sorprende che non fosse così ovvio a prima vista ...
François Févotte,

6
in alternativa potresti scriverlo come (list (cons "address" address))se non volessi usare i backtick
Jordon Biondo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.