common-lispclos

How to access slots within a class?


Given a class definition, is it possible to define one slot in terms of another, similar to how I would do it with let*?

For example, I would like to be able to do something like this (which obviously doesn't work):

(defclass foo ()
  ((x :initform 1 :accessor x)
   (y :initform (+ 1 x) :accessor y)))

Solution

  • In DEFCLASS slot descriptions one can't refer to slots.

    A typical way is to write an :after method for initialize-instance:

    (defclass foo ()
      ((x :initform 1 :accessor foo-x)
       (y             :accessor foo-y)))
    
    (defmethod initialize-instance :after ((object foo) &rest args)
      (with-slots (x y) object
        (setf y (1+ x))))
    
    CL-USER 44 > (make-instance 'foo)
    #<FOO 81B0161EEB>
    
    CL-USER 45 > (describe *)
    
    #<FOO 81B0161EEB> is a FOO
    X      1
    Y      2