Простое использование request.el

9

Мой неловко простой вопрос заключается в следующем:

Почему работает следующий код:

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

Пока этого нет?

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

Как мне отправить параметр на запрос?

baol
источник

Ответы:

11

Это потому, что '(("address" . address))в кавычках (то есть с префиксом 'оператора), что означает, что то, что находится внутри, не оценивается. Таким requestобразом, функция вызывается с аргументом, который является неоцененным address символом (тогда как в вашей первой реализации requestфункция получает строковую строку, которую не нужно сначала оценивать).

Вы можете исправить это двумя способами:

1) квазицитирование аргумента, которое позволяет вам получить в основном то же поведение, но указать части, которые все еще должны быть оценены:

`(("address" . ,address))

Обратите внимание, что одиночная кавычка ( ') была заменена на backquote ( `), и ранее ,был добавлен специальный маркер, addressчтобы указать, что он должен быть оценен и заменен его значением.

2) (согласно комментарию @ JordonBiondo) построение структуры явно с использованием примитивов, таких как listили cons. В вашем случае это будет сделано так:

(list (cons "address" address))

где, опять же, "address"строковый литерал (который оценивает сам себя), и addressвычисляется, поскольку он является аргументом в вызове функции.

Франсуа Февотт
источник
Спасибо за объяснение. Это улучшается, но теперь я получаю «Неверный аргумент типа: integerp, \,» :(
baol
Ах, хорошо: gnu.org/software/emacs/manual/html_node/elisp/Quoting.html это обратная цитата !!
Баол
1
Я добавил ссылки на соответствующие части руководства, чтобы сделать его более понятным. И я также прямо упомянул
обратную цитату,
6
В качестве альтернативы вы можете написать это так, как (list (cons "address" address))будто вы не хотите использовать обратные пометки
Джордон Биондо,