Сравнение возвращает каталог функции вызова ожидаемого значения, но это не так в процессе в списке - PullRequest
0 голосов
/ 11 ноября 2018

Я создаю простой тестер 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 Ответ

0 голосов
/ 11 ноября 2018

Ваш аргумент 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 вместо того, чтобы кататься самостоятельно.

...