Uso request.el simples

9

Minha pergunta embaraçosamente fácil é a seguinte:

Por que o código a seguir funciona:

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

Enquanto este não?

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

Como devo enviar um parâmetro para solicitar?

baol
fonte

Respostas:

11

Isso ocorre porque '(("address" . address))é citado (ou seja, prefixado pelo 'operador), o que significa que o que está dentro não é avaliado. A requestfunção é chamada assim com um argumento que é o address símbolo não avaliado (enquanto na sua primeira implementação, a requestfunção obtém uma string literal, que não precisa ser avaliada primeiro).

Você pode corrigir isso de duas maneiras:

1) quase citando o argumento, que permite obter basicamente o mesmo comportamento, mas especificar partes que ainda precisam ser avaliadas:

`(("address" . ,address))

Observe que as aspas simples ( ') foram substituídas por aspas ( `) e um marcador especial ,foi adicionado antes addresspara indicar que deveria ser avaliado e substituído por seu valor.

2) (como no comentário de @ JordonBiondo) construindo a estrutura explicitamente usando primitivas como listor cons. No seu caso, isso seria feito assim:

(list (cons "address" address))

onde, novamente, "address"é uma string literal (que é avaliada por si mesma) e addressé avaliada, pois é o argumento em uma chamada de função.

François Févotte
fonte
Obrigada pelo esclarecimento. Ele está melhorando, mas agora eu recebo "argumento de tipo errado: integerp, \", :(
Baol
11
Adicionei links para partes relevantes do manual para torná-lo mais claro. E eu também mencionado explicitamente o acento grave, uma vez que sem surpresa não era tão óbvio à primeira vista ...
François Févotte
6
Alternativamente, você poderia escrever isso como (list (cons "address" address))se você não quer backticks uso
Jordon Biondo