Сравнение возвращает каталог функции вызова ожидаемого значения, но это не так в процессе в списке
Я создаю простой тестер 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
1 ответ
Ваш аргумент 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))
,
Обратите внимание, что тот факт, что вам нужно eval
это очень сильный показатель того, что вы делаете что-то ужасно неправильно.
PS. Я призываю вас использовать ERT вместо того, чтобы кататься самостоятельно.