Einfache Verwendung von request.el

9

Meine peinlich einfache Frage lautet wie folgt:

Warum funktioniert der folgende Code:

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

Während dieser nicht?

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

Wie soll ich einen Parameter zur Anfrage senden?

baol
quelle

Antworten:

11

Dies liegt daran, dass '(("address" . address))in Anführungszeichen gesetzt wird (dh vom 'Operator vorangestellt wird ), was bedeutet, dass das, was sich darin befindet, nicht ausgewertet wird. Die requestFunktion wird daher mit einem Argument aufgerufen, das das nicht bewertete address Symbol ist (während die requestFunktion in Ihrer ersten Implementierung einen String litteral erhält, der nicht zuerst ausgewertet werden muss).

Sie können dies auf zwei Arten beheben:

1) Quasi-Zitat des Arguments, das es Ihnen ermöglicht, größtenteils das gleiche Verhalten zu erzielen, aber Teile anzugeben, die noch bewertet werden müssen:

`(("address" . ,address))

Beachten Sie, dass das einfache Anführungszeichen ( ') durch ein hinteres Anführungszeichen ( `) ersetzt wurde und zuvor ein spezieller Marker ,hinzugefügt wurde, addressum anzuzeigen, dass es ausgewertet und durch seinen Wert ersetzt werden sollte.

2) (gemäß @ JordonBiondos Kommentar) Erstellen der Struktur explizit unter Verwendung von Grundelementen wie listoder cons. In Ihrem Fall würde dies folgendermaßen geschehen:

(list (cons "address" address))

Dabei ist wiederum "address"ein Zeichenfolgenliteral (das sich selbst auswertet) und addresswird ausgewertet, da es das Argument in einem Funktionsaufruf ist.

François Févotte
quelle
Danke für die Erklärung. Es verbessert sich, aber jetzt bekomme ich "Falsches Argument: integerp, \" :(
baol
Ah, ok: gnu.org/software/emacs/manual/html_node/elisp/Quoting.html das ist ein Backquote !!
Baol
1
Ich habe Links zu relevanten Teilen des Handbuchs hinzugefügt, um es klarer zu machen. Und ich erwähnte auch ausdrücklich das Backquote, da es auf den ersten Blick nicht so offensichtlich war ...
François Févotte
6
Alternativ könnten Sie das so schreiben, als (list (cons "address" address))ob Sie keine Backticks verwenden möchten
Jordon Biondo