(URL检索)符号的值作为变量无效

时间:2019-02-13 16:30:50

标签: elisp

我有一个从github存储库中检索IP的功能。第一次调用该函数时,出现错误“符号的变量值无效:响应”,但第一次调用后的所有后续调用均成功。我尝试添加(require'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 :(得分:1)

您不应创建全局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) "")))))