2012-06-10 20 views
5

以下のコードは共通のlispで動作しますが、emacs lispでは "(エラー"メソッドのパラメータに "Unknown class type orc")というエラーがあります。なぜ、私はemacs lispで修正できますか?ありがとう。共通lispとemacs lispの構造の相違点

(defun randval (n) 
    (1+ (random (max 1 n)))) 

(defstruct monster (health (randval 10))) 

(defstruct (orc (:include monster)) (club-level (randval 8))) 

(defmethod monster-show ((m orc)) 
    (princ "A wicked orc with a level ") 
    (princ (orc-club-level m)) 
    (princ " club")) 

答えて

3

事がある... defmethodは、クラス、構造体ではないことを、それを必要とし、elispの中に構造体はちょうどベクトルです。たぶんあなたは自分のジェネリックディスパッチメソッドを思いつくかもしれませんが、おそらく構造体の代わりにクラスを使うだけで解決できます - クラスはeieio.elで実装されているので、内部を見てディスパッチする方法を見てください。それは実際にそこにあるどのように多くのクラスの生き物のに依存するであろう

(defun foo (monster) 
    (cond 
    ((eql (aref monster 0) 'cl-orc-struct) ...) ; this is an orc 
    ((eql (aref mosnter 0) 'cl-elf-struct) ...) ; this is an elf 
    (t (error "Not a mythological creature")))) 

、おそらくあなたが条件を隠すか、むしろ基づいてコールする関数を返すいくつかのマクロを思い付くことができます:それとも、単にようにそれが何かかもしれませんタイプタグなど

以下は、構造体に固執したくない場合や、多くの機能を必要としない場合や、独自に実装するのが喜んでいる場合に備えて、独自のジェネリックを作成するための簡単なアイデアです。

(defvar *struct-dispatch-table* (make-hash-table)) 

(defun store-stuct-method (tag method definition) 
    (let ((sub-hash 
    (or (gethash method *struct-dispatch-table*) 
     (setf (gethash method *struct-dispatch-table*) 
      (make-hash-table))))) 
    (setf (gethash tag sub-hash) definition))) 

(defun retrieve-struct-method (tag method) 
    (gethash tag (gethash method *struct-dispatch-table*))) 

(defmacro define-struct-generic (tag name arguments) 
    (let ((argvals (cons (caar arguments) (cdr arguments)))) 
    `(defun ,name ,argvals 
     (funcall (retrieve-struct-method ',tag ',name) ,@argvals)))) 

(defmacro define-struct-method (name arguments &rest body) 
    (let* ((tag (cadar arguments)) 
    (argvals (cons (caar arguments) (cdr arguments))) 
    (generic)) 
    (if (fboundp name) (setq generic name) 
     (setq generic 
     `(define-struct-generic 
      ,tag ,name ,arguments))) 
    (store-stuct-method 
    tag name 
    `(lambda ,argvals ,@body)) generic)) 

(define-struct-method test-method ((a b) c d) 
    (message "%s, %d" a (+ c d))) 

(test-method 'b 2 3) 
"b, 5" 
+0

ありがとうございます、私はdefclassをチェックします。 – louxiu

関連する問題