common-lisp
CLOS Meta-Object Protocol
Zoeken…
Verkrijg de slotnamen van een klasse
Laten we zeggen dat we een klas hebben als
(defclass person ()
(name email age))
Om de namen van de slots van de klasse te verkrijgen, gebruiken we de functie class-slots. Dit is te vinden in het closer-mop-pakket, geleverd door het closer-mop-systeem. Om het de lopende lisp-afbeelding te laden gebruiken we (ql:quickload :closer-mop)
. We moeten ook zorgen dat de klasse definitief is voordat we class-slots aanroepen.
(let ((class (find-class 'person)))
(c2mop:ensure-finalized class)
(c2mop:class-slots class))
die een lijst met effectieve slotdefinitieobjecten retourneert:
(#<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION S/TRANSFORMATIONS::NAME>
#<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION S/TRANSFORMATIONS::EMAIL>
#<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION S/TRANSFORMATIONS::AGE>)
Werk een slot bij wanneer een ander slot wordt gewijzigd
De CLOS MOP biedt de haak slot-waarde-gebruik-klasse, die wordt genoemd wanneer een slot is waarde wordt benaderd, gelezen of gewijzigd. Omdat we in dit geval alleen voor wijzigingen zorgen, definiëren we een methode voor (setf slot-value-using-class)
.
(defclass document ()
((id :reader id :documentation "A hash computed with the contents of every other slot")
(title :initarg :title :accessor title)
(body :initarg :body :accessor body)))
(defmethod (setf c2mop:slot-value-using-class) :after
(new class (object document) (slot c2mop:standard-effective-slot-definition))
;; To avoid this method triggering a call to itself, we check that the slot
;; the modification occurred in is not the slot we are updating.
(unless (eq (slot-definition-name slot) 'id)
(setf (slot-value object 'id) (hash-slots object))))
Merk op dat omdat bij het aanmaken van een slot-value
niet nodig kan zijn om de code in het initialize-instance :after
te dupliceren initialize-instance :after
methode
(defmethod initialize-instance :after ((obj document) &key)
(setf (slot-value obj 'id)
(hash-slots obj)))