[LISP] Récupérer les informations sur une structure puis parcourir les slots de ses instances
par
, 04/03/2019 à 16h03 (840 Affichages)
Lorsque vous utilisez des structures sous LISP, il peut ne pas être évident de savoir quels slots sont définis, notamment lors de la reprise d'une image. Ou simplement pour renvoyer de manière la plus simple et rapide possible, la liste dans un flux.
Pour réaliser ceci, je me suis penché sur le fonctionnement de describe, que je vous invite fortement à découvrir dans le détail.
-> Voir tout particulièrement (defmethod describe-object ((symbol symbol) stream) ...
Admettons que vous ayez une structure "triplet" définie ainsi :
Code lisp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 (defstruct triplet (groupe 0) (etat 0) (date (get-universal-time)) (poids 0) (sujet "") (prédicat "") (objet "") )
Grâce au package "sb-impl" - pour le cas de SBCL -, vous pouvez retrouver l'ensemble de ces slots et leur composition assez facilement en jonglant un peu :
Code lisp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 (in-package "SB-IMPL") (defun extraire-slots (objet) (let ( (structuration (find-defstruct-description objet)) ; structuration de la structure (slots nil) ) (setf slots (sb-impl::dd-slots structuration)) ; la liste ici, des slots à partir de la structuration (loop for slot in slots collect (dsd-name slot) ; on collecte les noms, mais nous pourrions aussi avoir le type (-type), les valeurs par défaut (-default), si le slot est en lecture seule (-read-only), etc. ) ) )
Vous pouvez ainsi à tout moment définir la liste des slots d'une structure et vous servir de cette liste, par exemple :
Code lisp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 (defparameter *triplets-attributs* (extraire-slots 'triplet) ) (defvar montriplet (make-triplet)) (loop for slot in *triplets-attributs* do (format t "~s : ~s~%" slot (slot-value montriplet slot) ) )
Ce qui renverra en console, un retour comme suivant :
Code lisp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 GROUPE : 0 ETAT : 0 DATE : 3760699737 POIDS : 0 SUJET : "" PRÉDICAT : "" OBJET : ""
Pratique !