It can also be used on objects defined by @code{cl-defstruct}.
This is a generalized variable that can be used with @code{setf} to
-modify the value stored in @var{slot}, tho not for objects defined by
-@code{cl-defstruct}.
+modify the value stored in @var{slot}.
@xref{Generalized Variables,,,elisp,GNU Emacs Lisp Reference Manual}.
@end defun
))
;; Now that everything has been loaded up, all our lists are backwards!
- ;; Fix that up now and then them into vectors.
+ ;; Fix that up now and turn them into vectors.
(cl-callf (lambda (slots) (apply #'vector (nreverse slots)))
(eieio--class-slots newc))
(cl-callf nreverse (eieio--class-initarg-tuples newc))
nil
;; Trim off object IDX junk added in for the object index.
(setq slot-idx (- slot-idx (eval-when-compile eieio--object-num-slots)))
- (let ((st (cl--slot-descriptor-type (aref (eieio--class-slots class)
- slot-idx))))
- (if (not (eieio--perform-slot-validation st value))
- (signal 'invalid-slot-type
- (list (eieio--class-name class) slot st value))))))
+ (let* ((sd (aref (eieio--class-slots class)
+ slot-idx))
+ (st (cl--slot-descriptor-type sd)))
+ (cond
+ ((not (eieio--perform-slot-validation st value))
+ (signal 'invalid-slot-type
+ (list (eieio--class-name class) slot st value)))
+ ((alist-get :read-only (cl--slot-descriptor-props sd))
+ (signal 'eieio-read-only (list (eieio--class-name class) slot)))))))
(defun eieio--validate-class-slot-value (class slot-idx value slot)
"Make sure that for CLASS referencing SLOT-IDX, VALUE is valid.
(defun eieio-oset (obj slot value)
"Do the work for the macro `oset'.
Fills in OBJ's SLOT with VALUE."
- (cl-check-type obj eieio-object)
+ (cl-check-type obj (or eieio-object cl-structure-object))
(cl-check-type slot symbol)
(let* ((class (eieio--object-class obj))
(c (eieio--slot-name-index class slot)))
;;
(define-error 'invalid-slot-name "Invalid slot name")
(define-error 'invalid-slot-type "Invalid slot type")
+(define-error 'eieio-read-only "Read-only slot")
(define-error 'unbound-slot "Unbound slot")
(define-error 'inconsistent-class-hierarchy "Inconsistent class hierarchy")
;;;; Interaction with defstruct
-(cl-defstruct eieio-test--struct a b c)
+(cl-defstruct eieio-test--struct a b (c nil :read-only t))
(ert-deftest eieio-test-defstruct-slot-value ()
(let ((x (make-eieio-test--struct :a 'A :b 'B :c 'C)))
(should (eq (eieio-test--struct-b x)
(slot-value x 'b)))
(should (eq (eieio-test--struct-c x)
- (slot-value x 'c)))))
+ (slot-value x 'c)))
+ (setf (slot-value x 'a) 1)
+ (should (eq (eieio-test--struct-a x) 1))
+ (should-error (setf (slot-value x 'c) 3) :type 'eieio-read-only)))
(provide 'eieio-tests)