2012-06-10 14 views
5

के बीच संरचना अंतर सामान्य लिस्प में काम करता है, लेकिन emacs lisp में, यह शिकायत करता है "(त्रुटि" विधि पैरामीटर में अज्ञात वर्ग प्रकार ओआरसी ")"। मैं इसे emacs 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 को एक वर्ग होने की आवश्यकता है, संरचना नहीं, ईएलआईएसपी में structs केवल वैक्टर हैं। हो सकता है कि आप अपनी जेनेरिक प्रेषण विधि के साथ आ सकें, लेकिन संभवतः केवल structs के बजाय कक्षाओं का उपयोग करने से इसे हल किया जाएगा - कक्षाएं 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")))) 

यह वास्तव में कैसे प्राणियों की कई श्रेणियां हैं पर निर्भर करेगा, शायद आप कुछ मैक्रो हालत छुपाता है या बल्कि रिटर्न कार्य के आधार पर कॉल करने के लिए साथ आ सकता है टाइप टैग इत्यादि

नीचे अपने स्वयं के जेनेरिक बनाने के लिए एक सरल विचार है, बस अगर आप structs के साथ रहना चाहते हैं और आपको बहुत सारी कार्यक्षमता की आवश्यकता नहीं है या इसे स्वयं लागू करने में प्रसन्नता हो रही है:

(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

धन्यवाद, मैं डिफ्लैस की जांच करूंगा। – louxiu