Next: Compiler Transformations, Up: Slot-Value
All of the following, while described in terms of slot-value
,
also applies to (setf slot-value)
and to slot-boundp
, and
could in principle be extended to slot-makunbound
.
The basic implementation of slot-value
, following the suggestion
in the standards document, is shown in ex:slot-value; the
implementation of the other slot operators is similar. The work to be
done simply to arrive at the generic function call is already
substantial: we need to look up the object's class and iterate over the
class' slots to find a slot of the right name, only then are we in a
position to call the generic function which implements the slot access
directly.
(defun slot-value (object slot-name) (let* ((class (class-of object)) (slot-definition (find-slot-definition class slot-name))) (if (null slot-definition) (values (slot-missing class object slot-name 'slot-value)) (slot-value-using-class class object slot-definition))))
Example 7.1
The basic implementation of slot-value-using-class
specialized on
the standard metaobject classes is shown in
ex:slot-value-using-class. First, we check for an obsolete
instance (that is, one whose class has been redefined since the object
was last accessed; if it has, the object must be updated by
update-instance-for-redefined-class
); then, we acquire the slot's
storage location from the slot definition, the value from the instance's
slot vector, and then after checking the value against the internal unbound
marker, we return it.
(defmethod slot-value-using-class ((class std-class) (object standard-object) (slotd standard-effective-slot-definition)) (check-obsolete-instance object) (let* ((location (slot-definition-location slotd)) (value (etypecase location (fixnum (clos-slots-ref (instance-slots object) location)) (cons (cdr location))))) (if (eq value +slot-unbound+) (values (slot-unbound class object (slot-definition-name slotd))) value)))
Example 7.2
Clearly, all of this activity will cause the performance of clos slot access to compare poorly with structure slot access; while there will be of necessity a slowdown between the slot accesses because the structure class need not be redefineable (while redefinition of standard-object classes is extremely common), the overhead presented in the above implementation is excessive.