Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lisp: Iterating over slots with a macro

With this:

(defclass test-class ()
  ((data :initarg :data)
   (other :initarg :other)))

(defmethod test ((tc test-class) &key)
  (macrolet ((print-slot (slot)
               `(with-slots (,slot) tc
                  (format t "slot value: ~a~%" ,slot))))
    (print-slot data)
    (print-slot other)))

I can do:

CL-USER> (test (make-instance 'test-class :data "data" :other "other"))
slot value: data
slot value: other

But I can't seem to iterate over them:

(defmethod test ((tc test-class) &key)
  (macrolet ((print-slot (slot)
               `(with-slots (,slot) tc
                  (format t "slot value: ~a~%" ,slot))))
    (dolist (slot '(data other))
      (print-slot slot))))
CL-USER> (test (make-instance 'test-class :data "data" :other "other"))
When attempting to read the slot's value (slot-value), the slot
SLOT is missing from the object #<TEST-CLASS {1001E3FFB3}>.
   [Condition of type SB-PCL::MISSING-SLOT]

Any idea how I can get this effect?

like image 715
John Graham Avatar asked Nov 17 '25 07:11

John Graham


1 Answers

Use a function, not a macro, so the argument will be evaluated.

(defmethod test ((tc test-class) &key)
  (flet ((print-slot (slot)
           (format t "slot value: ~a~%" (slot-value tc slot))))
    (dolist (slot '(data other))
      (print-slot slot))))
like image 165
Barmar Avatar answered Nov 20 '25 06:11

Barmar