Lisp 比较返回调用函数目录的期望值,但列表上的进程不是这样

Lisp 比较返回调用函数目录的期望值,但列表上的进程不是这样,lisp,elisp,funcall,Lisp,Elisp,Funcall,我正在创建一个简单的elisp测试仪。 然而,我得到了如下所示的错误行为(我无法理解) 我认为测试人员应该自然地返回t测试用例(:eq'a'a)和(:eq(返回符号)'a),因为我的测试人员也在下面的代码之前。事实并非如此 下面的代码已经超出了必要性,但在大多数情况下,它是在检查明显的行为 我认为我的测试人员也应该返回那些预期的返回值 有什么好主意吗? 甚至解释这种行为的原因都有助于改进我的测试人员。如果你能给我点东西,我将不胜感激 ;; return-symbol is always retu

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

我认为测试人员应该自然地返回
t
测试用例
(:eq'a'a)
(:eq(返回符号)'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
;;返回符号总是返回“a”
(defun返回符号()
"a)
;; => 返回符号
;; 返回符号的操作检查
(返回符号)
;; => A.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 通过等式比较“a”和“a”
(等式‘a’a)
;; => T
;; 用等号比较“a”和“a”
(等于‘a’a)
;; => T
;; 通过等式比较(返回符号)和“a”
(等式(返回符号)'a)
;; => T
;; 通过等式比较(返回符号)和(返回符号)
(等式(返回符号)(返回符号))
;; => T
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 通过函数化eq进行比较
(funcall'eq'a'a)
;; => T
(funcall'eq(返回符号)'a)
;; => T
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 带内接符号的funcall
(funcall(实习“eq”)‘a’a)
;; => T
(funcall(内部“eq”)(返回符号)'a)
;; => T
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 定义通用比较函数
(拆卸多组件(图例a和b)
“键是funcname符号,例如:funcname”
(let((funcname(替换字符串“^:+”(符号名键))中的regexp)
(funcall(实习生funcname)a b)
;; => 多重补偿
;; 多组件运行检查
(多重补偿:等式“a”a)
;; => T
(多组件:eq(返回符号)'a)
;; => T
(多重补偿:相等(返回符号)'a)
;; => T
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 定义要按顺序应用的函数
(卸载运行测试(测试)
“测试是一个列表,例如(([str]TESTNAME([sym]:FUNC[sexp]A[sexp]B))
([str]TESTNAME([sym]:FUNC[sexp]A[sexp]B))…)
(dolist(x测试)
(let*((测试名称(车辆x))
(价值(cadr x))
(键(第n个0值))
(a(第n个1值))
(b(第n个2个值)))
(如果(多组码a b)
(princ(传递了格式“%s”\n“testname))
(princ(格式“%s”失败\n“testname()()())))
;; => 运行测试
;; 运行测试的运行检查
(运行测试’((“eq1”)(:等式'a'a))
(“eq2”(:eq(返回符号)(返回符号)))
(“等式1”(:等于'a'a))
(“相等2”(:相等(返回符号)'a))
(“equal3”(:相等(返回符号)(返回符号()))))
;; =>

;; eq1失败 您的
运行测试的参数
会被计算一次,因此
“eq1”
会看到
'a
,它是
(引号a)
(长度为2的列表),当然,在
eq
下失败。 类似地,
(返回符号)
也不会被计算,
“eq1”
会在
eq
下看到长度1不相同的列表

只需将
print
添加到
multi-comp
,您就会发现

如果您将
(多comp键a b)
替换为
(多comp键(eval a)(eval b))
,您的代码可能会起作用

请注意


注:我建议您使用,而不是自己滚动。

我误解了(多重比较键(评估a)(评估b))是错误的,因为(评估a)是错误的。精算师,(eval a)是(eval'a),所以它返回'a!!非常感谢。我知道有ERT,但我用相同的代码测试Emacs-22到Emacs-26。所以我创建了一个新的测试框架@NaoyaYamashita:请注意,您需要eval这一事实是一个非常强烈的迹象,表明您正在做一些可怕的错误。