首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当返回nil时,Emacs Lisp:"if: No catch for tag:-catch nil-,t“

当返回nil时,Emacs Lisp:"if: No catch for tag:-catch nil-,t“
EN

Stack Overflow用户
提问于 2013-11-08 15:55:27
回答 1查看 1.6K关注 0票数 5

今天,我试着编写了一个elisp函数,除了函数返回时一直被抛出的错误外,所有的功能都很好。这是一个函数:(请原谅格式化,我还不知道如何缩进。)

代码语言:javascript
复制
(defun byte-is-readable (byte)
  "Determine whether BYTE is readable or not.
Returns t or nil."
  (if (and (<= byte 126) (>= byte 32)) t nil))

;; Read the 100 bytes of a file
;; If 10 in a row are not 'readable', it is safe to assume the file is a binary
(defun is-file-binary (file)
  "Determine whether FILE is a binary file.
Returns t or nil."
  (let* ((i 1)
         (c 0)
         (size (nth 7 (file-attributes file)))
         (lim (if (< size 100) size 100)))
    (while (< i lim)
      (let ((char (with-temp-buffer
                    (insert-file-contents file)
                    (buffer-substring i (+ i 1)))))
        (if (not (byte-is-readable (aref char 0)))
            (setq c (+ c 1))
          (setq c 0))
        (if (= c 10) (return t)))
      (setq i (+ i 1))))
  nil)

像这样调用它:(message "%s" (if (is-file-binary "/path/to/some/file") "true" "false")在返回true时工作文件,但在返回nil时抛出"if: No catch for tag:-catch nil-,t“。我猜这是因为没有得到正确的评估什么的。

我该怎么解决呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-08 16:11:04

错误来自于您在代码中使用了return。这是一个宏,它只在其他一些cl宏的上下文中进行有意义的扩展,例如loop

我鼓励您使用loop而不是while,因为它允许隐藏一些乏味的实现细节,如计数器、throw - catch机制等。但是,如果您出于任何原因想要使用while,那么从while循环中分离出来的方法是使用:

代码语言:javascript
复制
(catch 'label (while <condition> ... (throw 'label <result>)))

使用loop的代码版本。

代码语言:javascript
复制
(defun byte-readable-p (byte)
  "Determine whether BYTE is readable or not.
Returns t or nil."
  (cl-case byte
    ((?\n ?\r ?\t) t)
    (otherwise (and (<= byte 126) (>= byte 32)))))

(defun file-binary-p (file)
  "Determine whether FILE is a binary file.
Returns t or nil."
  (with-temp-buffer
    (insert-file-contents file)
    (cl-loop for c across
             (buffer-substring-no-properties
              1 (min 100 (buffer-size)))
             thereis (not (byte-readable-p c)))))

(file-binary-p (expand-file-name "~/.emacs"))
nil

(file-binary-p (expand-file-name "~/.emacs.d/elpa/w3m-20131021.2047/w3m.elc"))
t

或者,更短的版本,使用高阶函数:

代码语言:javascript
复制
(defun file-binary-p (file)
  "Determine whether FILE is a binary file.
Returns t or nil."
  (with-temp-buffer
    (insert-file-contents file)
    (cl-find-if-not 'byte-readable-p
                    (buffer-substring-no-properties
                     1 (min 100 (buffer-size))))))

注意,在传统的Lisp代码函数中,返回布尔值(通常称为“谓词”)是使用方案命名的:<word>p<word>-<word>-p,而不是is-<word>

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19863249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档