2012-06-10 24 views
5

Aşağıdaki kod, genel lisp'de çalışır, ancak emacs lisp'de "(" Yöntem parametrelerindeki bilinmeyen sınıf türü orc ")" hatasını "yazar. Neden ve nasıl emacs lisp'de tamir edebilirim? Teşekkürler.Ortak lisp ile emacs lisp arasındaki yapısal fark

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

cevap

3

Sorun şu ki ... defmethod'un bir sınıfa değil, bir yapısına ihtiyacı var, eLisp'teki yapılar yalnızca vektörlerdir. Belki kendi jenerik gönderim yönteminizle gelebilirsiniz, ancak muhtemelen sadece yapıların yerine sınıfları kullanmanız bunu çözecektir - sınıflar eieio.el'de uygulanmaktadır, böylece bunların iç tarafına bakabilir ve nasıl gönderdiklerini görebilirsiniz. Veya sadece bunu gibi bir şey olabilir: Gerçekten kaç ders yaratıkların orada bağlı olacağını

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

, muhtemelen dayalı çağrı fonksiyonu koşulunu gizler doğrusu döndüren bazı makro ile gelebilir Yazı tipi vb.

Kendi yapılılarınızı yapmak için basitleştirilmiş bir fikir aşağıdadır; yalnızca yapılara bağlı kalmak istediğinizde ve çok fazla işleve gerek duymuyorsanız veya bunu kendi başınıza uygulamaktan mutluluk duyuyorsanız:

(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

Teşekkürler, Defclass'ı kontrol edeceğim. – louxiu