2017-03-06 7 views
2

Common Lispの汎用関数からメソッドのリストを抽出する方法はありますか?たとえば
:これはCのAPIを介して行うことができますので、もし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をターゲットにしています - それは大丈夫です。
私は次のトリックを行うために、これを必要とする:第二部のために、(CLOS protocolを参照)

(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)) 

答えて

4

汎用関数generic-function-methodsは、一般的な機能のすべてのメソッドを取得するにはCLOSで利用可能ですが、それに注意してくださいあなたの質問を、あなたは(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 
+0

大丈夫、しかし方法「クローン」することが可能であり、他の一般的な機能にそのコピーを添付? – AlexDarkVoid

+0

この質問の回答を見ることができます:http://stackoverflow.com/questions/11067899/is-there-a-generic-method-for-cloning-clos-objects – Renzo

+0

@Renzo Thats clonigオブジェクト。彼は、この答えで行われたオリジナルを破壊することなく、2つの一般的な方法の間でマージを行いたいと考えています。おそらく誰かが何とかそれを代理することができますか? – Sylwester

関連する問題