Как добавить новый специализатор в cl-defmethod и применить к нескольким основным режимам? - PullRequest
0 голосов
/ 16 февраля 2020

Как я могу расширить cl-defmethod для совпадения на нескольких major-mode с? В cl-generi c есть небольшая документация, но я не понимаю, что происходит с макросами обобщителя.

Например,

(cl-defgeneric my-gen-fun (arg)
  (message "%S" arg))

;; define this so it wouldn't affect other cc-derived modes, eg. java, awk, etc.
(cl-defmethod my-gen-fun (&context (major-mode c-mode c++-mode) arg)
  (message "c-%S" arg))

Я бы хотел, чтобы (my-gen-fun arg) печатал "c -" только в c-mode и c++-mode, но не в других cc -производные режимы, такие как java-mode или awk-mode. Как я могу добавить новый специалист для обработки этого случая?

1 Ответ

1 голос
/ 16 февраля 2020

&context похож на %optional в том, что он применяет также все последующие аргументы, поэтому он должен следовать после аргументов.

Но вещь (major-mode <foo>-mode) не распространяется на (major-mode <foo>-mode <bar>-mode) как вы предлагаете (хотя это по общему признанию было бы естественным продолжением). Так что вместо этого вы должны позвонить cl-defmethod дважды. Если тело большого размера, вы, вероятно, должны поместить его в отдельную функцию:

(defun my-gen-fun-c-body (arg)
  (message "c-%S" arg))

;; define this so it wouldn't affect other cc-derived modes, eg. java, awk, etc.
(cl-defmethod my-gen-fun (arg &context (major-mode c-mode))
   (my-gen-fun-c-body arg))
(cl-defmethod my-gen-fun (arg &context (major-mode c++-mode))
   (my-gen-fun-c-body arg))

У меня есть локальный патч к cl-generic.el, который добавляет предложенную вами функциональность «нескольких основных режимов», но после просмотра если я вижу, что это своего рода хак и вводит различные проблемы в кейсе.

Некоторые проблемы в кейсе связаны с тем, что CLOS не предлагает что-то вроде or или and, таких как специализированные :

(defmethod foo ((x (or (eql 4) cons))) ...)

это потому, что это может сделать "невозможным" найти правильное упорядочение применяемых методов (например, является ли приведенный выше специализатор более или менее конкретным c, чем (x list) или (x (or (eql 5) cons))?).

...