2012-06-10 37 views
5

Mã dưới đây hoạt động trong lisp thông thường, nhưng trong emacs lisp, nó than phiền "(lỗi" Unknown class type orc trong phương thức tham số ")". Tại sao và làm thế nào tôi có thể sửa chữa nó trong emacs lisp? Cảm ơn.Cấu trúc khác biệt giữa lisp thông thường và 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")) 

Trả lời

3

Điều này là ... defmethod cần nó là một lớp, không phải cấu trúc, cấu trúc trong eLisp chỉ là vectơ. Có lẽ bạn có thể đưa ra phương thức công văn chung của riêng bạn, nhưng có lẽ chỉ sử dụng các lớp thay vì cấu trúc sẽ giải quyết nó - các lớp được thực hiện trong eieio.el, vì vậy bạn có thể nhìn vào bên trong của nó và xem cách chúng xử lý. Hoặc bạn chỉ có thể có nó cái gì đó như:

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

Nó sẽ thực sự phụ thuộc vào có bao nhiêu lớp học của các sinh vật đang có, có lẽ bạn có thể đưa ra một số vĩ mô mà giấu đi tình trạng này hay đúng hơn là trả về chức năng nào được gọi dựa trên thẻ loại, vv

Dưới đây là một ý tưởng đơn giản để tạo ra các generics của riêng bạn, chỉ trong trường hợp bạn muốn gắn bó với cấu trúc và bạn không cần nhiều chức năng hoặc vui lòng tự mình thực hiện:

(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

Cảm ơn, tôi sẽ kiểm tra phân lớp. – louxiu

Các vấn đề liên quan