如何扩展cl-defmethod以匹配多个major-mode?在cl-generic中有一些文档,但我不明白泛型器宏是怎么回事。
举个例子,
(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-mode和c++-mode中都只打印"c-“,而不是其他cc派生的模式,如java-mode或awk-mode。如何添加新的specializer来处理这种情况?
发布于 2020-02-17 00:05:15
&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))) ...)这是因为它可能使它“不可能”找到适用方法的合理排序(例如,上面的特殊化器比(x list)或(x (or (eql 5) cons))更具体还是更具体?)。
https://stackoverflow.com/questions/60244133
复制相似问题