Penggunaan request.el sederhana

9

Pertanyaan mudah saya yang memalukan adalah sebagai berikut:

Mengapa kode berikut berfungsi:

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

Sementara yang ini tidak?

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

Bagaimana saya harus mengirim parameter untuk meminta?

baol
sumber

Jawaban:

11

Hal ini karena '(("address" . address))yang dikutip (yaitu diawali oleh 'operator), yang berarti bahwa apa yang di dalam tidak bisa dievaluasi. The requestFungsi demikian dipanggil dengan argumen yang merupakan unevaluated address simbol (sedangkan di implementasi pertama Anda, requestfungsi mendapat litteral string, yang tidak perlu dievaluasi pertama).

Anda dapat memperbaikinya dengan 2 cara:

1) kuasi-mengutip argumen, yang memungkinkan Anda untuk mendapatkan sebagian besar perilaku yang sama tetapi untuk menentukan bagian-bagian yang masih perlu dievaluasi:

`(("address" . ,address))

Perhatikan bahwa kutipan tunggal ( ') telah digantikan oleh tanda kutip ( `), dan penanda khusus ,ditambahkan sebelumnya addressuntuk menunjukkan bahwa itu harus dievaluasi dan diganti dengan nilainya.

2) (sesuai komentar @ JordonBiondo) membangun struktur secara eksplisit menggunakan primitif seperti listatau cons. Dalam kasus Anda, ini akan dilakukan seperti ini:

(list (cons "address" address))

di mana, sekali lagi, "address"adalah string literal (yang mengevaluasi sendiri), dan addressdievaluasi karena merupakan argumen dalam pemanggilan fungsi.

François Févotte
sumber
Terima kasih untuk penjelasannya. Itu membaik, tapi sekarang saya mendapatkan "Argumen tipe yang salah: integerp, \," :(
baol
Ah, ok: gnu.org/software/emacs/manual/html_node/elisp/Quoting.html itu adalah backquote !!
baol
1
Saya menambahkan tautan ke bagian-bagian yang relevan dari manual ini untuk membuatnya lebih jelas. Dan saya juga secara eksplisit menyebutkan backquote karena tidak mengherankan pada pandangan pertama ...
François Févotte 515
6
atau Anda dapat menulis bahwa seolah- (list (cons "address" address))olah Anda tidak ingin menggunakan backticks
Jordon Biondo