有没有办法从Common Lisp中的泛型函数中提取方法列表?
例如:
(defmethod say ((self string)) ; method-0
(format t "Got string: ~a~%" self))
(defmethod say ((self integer)) ; method-1
(format t "Got integer: ~a~%" self))
(defmethod say ((self symbol)) ; method-2
(format t "Got symbol: ~a~%" self))
(extract-methods-from-generic 'say) ; -> (method-0-obj method-1-obj method-2-obj)
更具体地说,我的目标是ECL,所以如果可以通过C API完成 - 那没关系。
我需要这个来做下一招:
(defgeneric merged-generic ())
(loop for method
in (extract-methods-from-generic 'some-generic-0)
do (add-method merged-generic method))
(loop for method
in (extract-methods-from-generic 'some-generic-1)
do (add-method merged-generic method))
答案 0 :(得分:4)
CLOS中提供了泛型函数generic-function-methods
以获取泛型函数的所有方法(请参阅CLOS protocol),但请注意,对于问题的第二部分,您可以附加只有当方法与任何其他泛型函数分离时,才能使用泛型函数(带add-method
)的方法(参见protocol):
如果该方法已与某些其他通用函数关联,也会发出错误信号。
您可以通过包closer-mop使用这两个功能,与任何实现无关:
CL-USER> (ql:quickload "closer-mop")
("closer-mop")
CL-USER> (in-package :closer-mop)
#<Package "CLOSER-MOP">
C2MOP> (defgeneric say (x))
#<COMMON-LISP:STANDARD-GENERIC-FUNCTION SAY #x30200176712F>
C2MOP> (defmethod say ((self string)) ; method-0
(format t "Got string: ~a~%" self))
(defmethod say ((self integer)) ; method-1
(format t "Got integer: ~a~%" self))
(defmethod say ((self symbol)) ; method-2
(format t "Got symbol: ~a~%" self))
#<COMMON-LISP:STANDARD-METHOD SAY (SYMBOL)>
C2MOP> (generic-function-methods #'say)
(#<COMMON-LISP:STANDARD-METHOD SAY (SYMBOL)> #<COMMON-LISP:STANDARD-METHOD SAY (INTEGER)> #<COMMON-LISP:STANDARD-METHOD SAY (STRING)>)
C2MOP> (defgeneric merged-generic (x))
#<COMMON-LISP:STANDARD-GENERIC-FUNCTION MERGED-GENERIC #x30200181B74F>
C2MOP> (add-method #'merged-generic (first **))
#<COMMON-LISP:STANDARD-METHOD SAY (SYMBOL)> is already a method of #<COMMON-LISP:STANDARD-GENERIC-FUNCTION SAY #x30200165863F>.
[Condition of type SIMPLE-ERROR]
; Evaluation aborted on #<SIMPLE-ERROR #x3020016719FD>.
CL-USER> (let ((first-method (first (generic-function-methods #'say))))
(remove-method #'say first-method)
(add-method #'merged-generic first-method))
#<COMMON-LISP:STANDARD-GENERIC-FUNCTION MERGED-GENERIC #x302000DC54DF>
CL-USER> (merged-generic "a string")
Got string: a string
NIL