&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))
?).