比较returns期望值调用函数目录,但在list process中不是这样
Comparison returns expected value call function directory, but it is not so at process on list
我正在创建一个简单的 elisp 测试器。
但是,我遇到了错误的行为(我无法理解),如下所示。
我认为测试人员应该 return t
测试用例 (:eq 'a 'a)
和 (:eq (return-symbol) 'a)
自然因为我的测试人员也在下面的代码之前。其实不然。
下面的代码已经过长,但大部分是在检查明显的行为。
我认为我的测试人员也应该 return 那些预期的 return 值。
有什么好主意吗?
即使解释这种行为的原因也有助于改进我的测试仪。如果你能给我一些东西,我将不胜感激。
;; 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.
PS。我强烈建议您使用 ERT 而不是自己滚动。
我正在创建一个简单的 elisp 测试器。 但是,我遇到了错误的行为(我无法理解),如下所示。
我认为测试人员应该 return t
测试用例 (:eq 'a 'a)
和 (:eq (return-symbol) 'a)
自然因为我的测试人员也在下面的代码之前。其实不然。
下面的代码已经过长,但大部分是在检查明显的行为。
我认为我的测试人员也应该 return 那些预期的 return 值。
有什么好主意吗? 即使解释这种行为的原因也有助于改进我的测试仪。如果你能给我一些东西,我将不胜感激。
;; 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.
PS。我强烈建议您使用 ERT 而不是自己滚动。