如果你用宏定义你的动物类,那么你可以让宏记录源代码。
示例(在 LispWorks 中工作):
例如,我们可以使用 alist 将源代码存储在类分配的插槽中。或者,您可以只使用一个简单的全局变量。
(defclass animal ()
((source :allocation :class :initform nil)))
上面有一个插槽,它应该指向一个类名和源代码的列表。
(defmacro def-animal-class (&whole code name feeding )
`(progn
(defclass ,name (animal) ())
(defmethod feed ((animal ,name)) ,@feeding)
(let ((item (assoc ',name
(slot-value (class-prototype (find-class 'animal))
'source))))
(if item
(setf (cdr item) ',code)
(setf (slot-value (class-prototype (find-class 'animal))
'source)
(list (cons ',name ',code)))))
',name))
生成的代码是什么样的?
CL-USER > (pprint (macroexpand-1 '(def-animal-class cat ((print "feeding a cat")))))
(PROGN
(DEFCLASS CAT (ANIMAL) NIL)
(DEFMETHOD FEED ((ANIMAL CAT)) (PRINT "feeding a cat"))
(LET ((ITEM (ASSOC 'CAT (SLOT-VALUE (CLASS-PROTOTYPE (FIND-CLASS 'ANIMAL))
'SOURCE))))
(IF ITEM
(SETF (CDR ITEM) '(DEF-ANIMAL-CLASS CAT ((PRINT "feeding a cat"))))
(SETF (SLOT-VALUE (CLASS-PROTOTYPE (FIND-CLASS 'ANIMAL)) 'SOURCE)
(LIST (CONS 'CAT '(DEF-ANIMAL-CLASS CAT ((PRINT "feeding a cat"))))))))
'CAT)
使用它:
CL-USER 75 > (def-animal-class cat ((print "feeding a cat some more")))
CAT
CL-USER 76 > (cdr (first (slot-value (class-prototype (find-class 'animal))
'source)))
(DEF-ANIMAL-CLASS CAT ((PRINT "feeding a cat some more")))
因此,每当使用宏时,都会记录最后一个源代码DEF-ANIMAL-CLASS
。然后,您可以例如将代码写入文件:
(with-open-file (s "~/animals.sexp" :direction :output :if-exists :supersede)
(pprint (slot-value (class-prototype (find-class 'animal)) 'source) s))
一个简单的READ
把它带回来。