Proste użycie request.el

9

Moje żenująco łatwe pytanie brzmi:

Dlaczego działa następujący kod:

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

Podczas gdy ten nie?

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

Jak mam wysłać parametr do żądania?

baol
źródło

Odpowiedzi:

12

Wynika to z tego, że '(("address" . address))jest cytowany (tzn. Jest poprzedzony przez 'operatora), co oznacza, że ​​to, co jest w środku, nie podlega ocenie. W requestten sposób funkcja jest wywoływana z argumentem, który jest nieocenionym address symbolem (podczas gdy w twojej pierwszej implementacji requestfunkcja otrzymuje ciąg literowy, który nie musi być najpierw oceniany).

Możesz to naprawić na 2 sposoby:

1) quasi-cytowanie argumentu, co pozwala uzyskać głównie takie samo zachowanie, ale określić części, które nadal wymagają oceny:

`(("address" . ,address))

Zauważ, że pojedynczy cudzysłów ( ') został zastąpiony przez cudzysłów ( ) `, a ,wcześniej dodano specjalny znacznik addresswskazujący, że należy go ocenić i zastąpić jego wartością.

2) (zgodnie z komentarzem @ JordonBiondo) budując strukturę jawnie, używając prymitywów takich jak listlub cons. W twoim przypadku można to zrobić w następujący sposób:

(list (cons "address" address))

gdzie znowu "address"jest literałem łańcuchowym (który ocenia się sam) i addressjest analizowany, ponieważ jest argumentem w wywołaniu funkcji.

François Févotte
źródło
Dziękuję za wyjaśnienie. Poprawia się, ale teraz pojawia się komunikat „Błędny typ argumentu: integerp, \,” :(
baol,
1
Dodałem linki do odpowiednich części instrukcji, aby było jaśniej. I wyraźnie wspomniałem również o
cytacie wstecz,
6
alternatywnie możesz napisać to tak (list (cons "address" address)), jakbyś nie chciał korzystać z tyknięć
Jordon Biondo