Last active
August 12, 2018 11:11
-
-
Save serialhex/b7ac95be24200a676e8e to your computer and use it in GitHub Desktop.
Get slots from a random struct. Can you do that in (Objective-)C(++|#)???
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun struct-slots (struct) | |
"Quick & dirty hack to get the slot names of a given struct" | |
(let ((data (cdr (read-from-string (string-left-trim "#S" (format nil "~S" struct)))))) | |
(labels ((pull-slot (s k) | |
(if s | |
(pull-slot (cddr s) (cons (car s) k)) | |
k))) | |
(pull-slot data nil)))) | |
;; it's not the prettiest/most efficient code, but it works! | |
;; so if I get a random struct, lets call it `black-box-struct` i can get the slots like thus: | |
(struct-slots black-box-struct) | |
;=> (letters numbers poops) | |
;; this only works if the default printer function hasn't been changed | |
;; (which is like 99% of use cases) | |
;; on the other hand, if you are using an actual CLOS class, you can do this: | |
(defun object-slots (obj) | |
(mapcar #'slot-definition-name (class-slots (class-of obj)))) | |
(object-slots black-box-obj) | |
;=> (things llamas monkeys) | |
;; you can pull it altogether like this: | |
(defun get-slots (thing) | |
(typecase thing | |
(structure (struct-slots thing)) | |
(standard-object (object-slots thing)) | |
(t (error "I can't get the slots of a ~A" thing)))) | |
(get-slots black-box-struct) | |
;=> (letters numbers poops) | |
(get-slots black-box-obj) | |
;=> (things llamas monkeys) | |
(get-slots "object") | |
;=> Error: I can't get the slots of a object |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment