(url-retrieve) Значение символа как переменной равно void - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть функция для получения IP-адреса из репозитория github.Я получаю сообщение об ошибке «Значение символа как переменная void: response» при первом вызове функции, но все последующие вызовы после первого являются успешными.Я пытался добавить (требуется 'URL), но безрезультатно.

(defun get-ip ()
  (let ((url-request-method "GET")
        (url-request-extra-headers 
         '(("Authorization" . "token xxxxxxxxx")
       ("Accept" . "application/vnd.github.v3.raw"))))
    (progn (url-retrieve "https://api.github.com/repos/xxxxxxx" 
             (lambda (status)
               (progn (setq response (buffer-substring (point-min) (point-max)))
                  (kill-buffer (current-buffer))))
             nil
             'silent)
       (string-match "\\([0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*\\)" response)
       (match-string 0 response))))

1 Ответ

0 голосов
/ 13 февраля 2019

Вы не должны создавать глобальную переменную response.Вместо этого добавьте его в форму let, чтобы он был локальным по отношению к defun.См. Также https://www.gnu.org/software/emacs/manual/html_node/elisp/Local-Variables.html

Более конкретно, url-retrieve - это асинхронная функция: код, который пытается установить response, еще не будет иметь буфера для работы, когда url-retrieve завершит оценку (будетпродолжить в фоновом режиме и в конечном итоге вызвать его обратный вызов в lambda, но нет никакой гарантии, что это произойдет во время выполнения вашей формы).Простое, но немного неуклюжее решение состоит в том, чтобы переключиться на url-retrieve-synchronously и жить с тем фактом, что это может занять некоторое время.

Вы также должны позаботиться о том, чтобы не загромождать буфер пользователя, его положение в этом буфере,или история матчей регулярных выражений.

С этими исправлениями также вполне естественно выделить response полностью.

(defun get-ip ()
  (let ((url-request-method "GET")
        (url-request-extra-headers 
         '(("Authorization" . "token xxxxxxxxx")
       ("Accept" . "application/vnd.github.v3.raw"))))
    (save-match-data
      (save-current-buffer
        (set-buffer
         (url-retrieve-synchronously "http://www.google.com/" 'silent))
        (goto-char (point-min))
        (if (search-forward-regexp "\\([0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*\\)" nil t)
            (match-string 0) "")))))
...