Skip to content

Instantly share code, notes, and snippets.

@serialhex
Last active August 12, 2018 11:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save serialhex/b7ac95be24200a676e8e to your computer and use it in GitHub Desktop.
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(++|#)???
(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