我有一个从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))))
答案 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) "")))))