lisp - 比较返回期望值调用函数目录,但在list上的process中却不是这样

标签 lisp elisp funcall

我正在创建一个简单的 elisp 测试器。 但是,我得到了错误的行为(我无法理解),如下所示。

我认为测试人员应该返回 t 测试用例 (:eq 'a 'a)(:eq (return-symbol) 'a) 作为我的测试人员,自然也会在下面的代码之前。其实不然。

以下代码已超出必要的长度,但在大多数情况下它是在检查明显的行为。

我认为我的测试人员也应该返回那些预期的返回值。

有什么好主意吗? 即使解释这种行为的原因也有助于改进我的测试仪。如果你能给我一些东西,我将不胜感激。

;; return-symbol is always return 'a
(defun return-symbol ()
  'a)
;; => return-symbol

;; operation check for return-symbol
(return-symbol)
;; => a

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; compare 'a and 'a by eq
(eq 'a 'a)
;; => t

;; compare 'a and 'a by equal
(equal 'a 'a)
;; => t

;; compare (return-symbol) and 'a by eq
(eq (return-symbol) 'a)
;; => t

;; compare (return-symbol) and (return-symbol) by eq
(eq (return-symbol) (return-symbol))
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; comparison by funcalled eq
(funcall 'eq 'a 'a)
;; => t

(funcall 'eq (return-symbol) 'a)
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; funcall with interned symbol
(funcall (intern "eq") 'a 'a)
;; => t

(funcall (intern "eq") (return-symbol) 'a)
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; define universal comparison function
(defun multi-comp (key a b)
  "KEY is funcname symbol such as :FUNCNAME"
  (let ((funcname (replace-regexp-in-string "^:+" "" (symbol-name key))))
    (funcall (intern funcname) a b)))
;; => multi-comp

;; operation check for multi-comp
(multi-comp :eq 'a 'a)
;; => t

(multi-comp :eq (return-symbol) 'a)
;; => t

(multi-comp :equal (return-symbol) 'a)
;; => t

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Define function to apply sequentially
(defun run-test (tests)
  "TESTS is list such as (([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))
                          ([str]TESTNAME ([sym]:FUNC [sexp]A [sexp]B))...)"
  (dolist (x tests)
    (let* ((testname (car x))
           (values   (cadr x))
           (key      (nth 0 values))
           (a        (nth 1 values))
           (b        (nth 2 values)))
      (if (multi-comp key a b)
          (princ (format "%s is passed\n" testname))
        (princ (format "%s is failed\n" testname))))))
;; => run-test

;; operation check of run-test
(run-test '(("eq1" (:eq 'a 'a))
            ("eq2" (:eq (return-symbol) (return-symbol)))
            ("equal1" (:equal 'a 'a))
            ("equal2" (:equal (return-symbol) 'a))
            ("equal3" (:equal (return-symbol) (return-symbol)))))
;; =>
;; eq1 is failed       ; <= ??
;; eq2 is failed       ; <= ??
;; equal1 is passed
;; equal2 is failed    ; <= ??
;; equal3 is passed
;; nil

最佳答案

你对 run-test 的论点被评估一次,所以"eq1"看到 'a这是 (quote a) (长度为 2 的列表)当然在 eq 下失败. 同样,(return-symbol)未评估且"eq1"看到长度为 1 的列表在 eq 下不相同.

您只需添加 print 就会发现这一点至 multi-comp .

如果您替换 (multi-comp key a b),您的代码可能会起作用与 (multi-comp key (eval a) (eval b)) .

请注意the fact that you need eval is a very strong indicator that you are doing something horribly wrong .

附言。我敦促你使用 ERT而不是自己滚动。

关于lisp - 比较返回期望值调用函数目录,但在list上的process中却不是这样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53245115/

相关文章:

lisp - 为什么我们需要 Lisp 中的 funcall?

c - 如何在没有 rb_string_eval 的情况下使用 C API 调用 ObjectSpace.each_object?

performance - 如何着手编写核心函数,而不是使用命令式风格?

emacs - 打开 emacs 并水平分割

emacs - [组织模式] : repeating task in every Mon, 周三、周五 18 点 :00, 需要有关 sexp 的帮助

emacs - (elisp) 向量的向量元素

elisp - 调用 elisp 函数并使其提示输入

lisp - Lisp 函数的零值

function - 从 lisp 中的整数列表中消除每次出现的 x