Is it possible to use a with-slots-type macro with an instance of a defstruct-defined class in emacs lisp? I tried and I'm getting this error:

eieio-oset: Wrong type argument: eieio-object, "some-string", obj. 

Sample code:

  (defstruct testobj a b)
  (require 'eieio)
  (with-slots (a b)  (make-testobj :a 1 :b 2)
    (message "value: %s:"  (list a b))))

While waiting for a better answer, I wrote a with-slots macro that seems to work with defstruct instances:

(defmacro my-with-slots (class-name slots obj &rest body)
  "Bind slot names SLOTS in an instance OBJ of class CLASS-NAME, and execute BODY."
  (declare (indent 3))
       ,(cl-loop for slot in slots
                 collect `(,slot (cl-struct-slot-value ',class-name ',slot ,obj)))

;; example
  (defstruct testobj a b)
  (let ((obj (make-testobj :a 1 :b 2)))
    (my-with-slots testobj (a b)  obj
      (message "value: %s:"  (list a b))
      (setq a 3 b 4)
      (message "value: %s:"  (list (testobj-a obj) (testobj-b obj))))))
| improve this answer | |
  • 2
    Instead of the intern which will fail if the defstruct specifies a different prefix, you can use cl-struct-slot-value. As you found out, currently, slot-value and with-slots are specific to EIEIO and only work on EIEIO objects. – Stefan Mar 8 '19 at 22:54
  • Thanks, edited answer. – erjoalgo Mar 12 '19 at 1:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.