CLOS:STANDARD-INSTANCE-ACCESSCLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESSCLOS:SET-FUNCALLABLE-INSTANCE-FUNCTIONCLOS:SLOT-VALUE-USING-CLASS(SETF CLOS:SLOT-VALUE-USING-CLASS)CLOS:SLOT-BOUNDP-USING-CLASSCLOS:SLOT-MAKUNBOUND-USING-CLASSThe instance structure protocol is responsible for implementing
the behavior of the slot access functions like SLOT-VALUE and
(.SETF SLOT-VALUE)
For each CLOS slot access function other than SLOT-EXISTS-P,
there is a corresponding generic function which actually provides the
behavior of the function. When called, the slot access function finds
the pertinent effective slot definition metaobject, calls the corresponding generic function and
returns its result. The arguments passed on to the generic function
include one additional value, the class of the object argument,
which always immediately precedes the object argument.
Table 29.6. The correspondence between slot access function and underlying slot access generic function
| Slot Access Function | Corresponding Slot Access Generic Function |
|---|---|
SLOT-VALUE object slot-name | CLOS:SLOT-VALUE-USING-CLASS class object slot |
( new-value object slot-name | (SETF CLOS:SLOT-VALUE-USING-CLASS) new-value class object slot |
SLOT-BOUNDP object slot-name | CLOS:SLOT-BOUNDP-USING-CLASS class object slot |
SLOT-MAKUNBOUND object slot-name | CLOS:SLOT-MAKUNBOUND-USING-CLASS class object slot |
At the lowest level, the instance structure protocol provides only limited mechanisms for portable programs to control the implementation of instances and to directly access the storage associated with instances without going through the indirection of slot access. This is done to allow portable programs to perform certain commonly requested slot access optimizations.
In particular, portable programs can control the implementation
of, and obtain direct access to, slots with allocation :INSTANCE and
type T. These are called directly accessible slots
.
The relevant specified around-method on CLOS:COMPUTE-SLOTS determines
the implementation of instances by deciding how each slot in the
instance will be stored. For each directly accessible slot, this method
allocates a location
and associates it with the effective slot definition metaobject.
The location can be accessed by calling the CLOS:SLOT-DEFINITION-LOCATION
generic function. Locations are non-negative integers. For a given
class, the locations increase consecutively, in the order that the
directly accessible slots appear in the list of effective slots. (Note
that here, the next paragraph, and the specification of this
around-method are the only places where the value returned by
CLOS:COMPUTE-SLOTS is described as a list rather than a set.)
Given the location of a directly accessible slot, the value of
that slot in an instance can be accessed with the appropriate accessor.
For STANDARD-CLASS, this accessor is the function
CLOS:STANDARD-INSTANCE-ACCESS. For CLOS:FUNCALLABLE-STANDARD-CLASS, this
accessor is the function CLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESS.
In each case, the arguments to the accessor are the instance and the
slot location, in that order. See the definition of each accessor for
additional restrictions on the use of these function.
Portable programs are permitted to affect and rely on the
allocation of locations only in the following limited way: By first
defining a portable primary method on CLOS:COMPUTE-SLOTS which orders the
returned value in a predictable way, and then relying on the defined
behavior of the specified around-method to assign locations to all
directly accessible slots. Portable programs may compile-in calls to
low-level accessors which take advantage of the resulting predictable
allocation of slot locations.
This example shows the use of this mechanism to implement a new
class metaobject class, ordered-class and class
option :SLOT-ORDER. This option provides control
over the allocation of slot locations. In this simple example
implementation, the :SLOT-ORDER option is not
inherited by subclasses; it controls only instances of the class
itself.
(defclass ordered-class (standard-class)
((slot-order :initform ()
:initarg :slot-order
:reader class-slot-order)))
(defmethod compute-slots ((class ordered-class))
(let ((order (class-slot-order class)))
(sort (copy-list (call-next-method))
#'(lambda (a b)
(< (position (slot-definition-name a) order)
(position (slot-definition-name a) order))))))
Following is the source code the user of this extension would write.
Note that because the code above does not implement inheritance of
the :SLOT-ORDER option, the function
distance must not be called on instances of
subclasses of point; it can only be called on
instances of point itself.
(defclass point ()
((x :initform 0)
(y :initform 0))
(:metaclass ordered-class)
(:slot-order x y))
(defun distance (point)
(sqrt (/ (+ (expt (standard-instance-access point 0) 2)
(expt (standard-instance-access point 1) 2))
2.0)))
You cannot assume that the slot-location
values start at 0. In class point, for
example, x and y will be at slot locations 1 and 2, not 0 and
1.
In more realistic uses of this mechanism, the calls to the low-level instance structure accessors would not actually appear textually in the source program, but rather would be generated by a meta-level analysis program run during the process of compiling the source program.
Instances of classes which are themselves instances of
CLOS:FUNCALLABLE-STANDARD-CLASS or one of its subclasses are called
funcallable instances.
Funcallable instances can only be created by
.ALLOCATE-INSTANCE
(CLOS:FUNCALLABLE-STANDARD-CLASS)
Like standard instances, funcallable instances have slots with the
normal behavior. They differ from standard instances in that they can
be used as functions as well; that is, they can be passed to FUNCALL
and APPLY, and they can be stored as the definition of a function
name. Associated with each funcallable instance is the function which
it runs when it is called. This function can be changed with
CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION.
The following simple example shows the use of funcallable
instances to create a simple, DEFSTRUCT-like facility. (Funcallable
instances are useful when a program needs to construct and maintain a
set of functions and information about those functions. They make it
possible to maintain both as the same object rather than two separate
objects linked, for example, by hash tables.)
(defclass constructor () ((name :initarg :name :accessor constructor-name) (fields :initarg :fields :accessor constructor-fields)) (:metaclass funcallable-standard-class)) ⇒#>FUNCALLABLE-STANDARD-CLASS CONSTRUCTOR>(defmethod initialize-instance :after ((c constructor)&KEY) (with-slots (name fields) c (set-funcallable-instance-function c #'(lambda () (let ((new (make-array (1+ (length fields))))) (setf (aref new 0) name) new))))) ⇒#<STANDARD-METHOD :AFTER (#<FUNCALLABLE-STANDARD-CLASS CONSTRUCTOR>)>(setq c1 (make-instance 'constructor :name 'position :fields '(x y))) ⇒#<CONSTRUCTOR #<UNBOUND>>(setq p1 (funcall c1)) ⇒#(POSITION NIL NIL)
CLOS:STANDARD-INSTANCE-ACCESSCLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESSCLOS:SET-FUNCALLABLE-INSTANCE-FUNCTIONCLOS:SLOT-VALUE-USING-CLASS(SETF CLOS:SLOT-VALUE-USING-CLASS)CLOS:SLOT-BOUNDP-USING-CLASSCLOS:SLOT-MAKUNBOUND-USING-CLASSCLOS:STANDARD-INSTANCE-ACCESS(CLOS:STANDARD-INSTANCE-ACCESS
instance location)instancelocationThis function is called to provide direct access to a slot in an instance. By usurping the normal slot lookup protocol, this function is intended to provide highly optimized access to the slots associated with an instance.
The following restrictions apply to the use of this function:
instance argument must be a
standard instance (it must have been returned by
ALLOCATE-INSTANCE(STANDARD-CLASS)).
instance argument cannot be an
non-updated obsolete instance.location argument must be a location of
one of the directly accessible slots of the instance's class.
The results are undefined if any of these restrictions are violated.
CLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESS(CLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESS
instance location)instancelocationThis function is called to provide direct access to a slot in an instance. By usurping the normal slot lookup protocol, this function is intended to provide highly optimized access to the slots associated with an instance.
The following restrictions apply to the use of this function:
instance argument must be a
funcallable instance (it must have been returned by
ALLOCATE-INSTANCE
(CLOS:FUNCALLABLE-STANDARD-CLASS)).instance argument cannot be an
non-updated obsolete instance.location argument must be a location of
one of the directly accessible slots of the instance's class.
The results are undefined if any of these restrictions are violated.
CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION(CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION
funcallable-instance function)
funcallable-instanceALLOCATE-INSTANCE
(CLOS:FUNCALLABLE-STANDARD-CLASS)).
functionCLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION is called, any subsequent calls
to funcallable-instance will run the new
function.CLOS:SLOT-VALUE-USING-CLASS(CLOS:SLOT-VALUE-USING-CLASS class
object slot)classobject argument.objectslotThis generic function implements the behavior of the
SLOT-VALUE function. It is called by SLOT-VALUE with the class
of object as its first argument and the pertinent effective slot definition metaobject as its
third argument.
The generic function CLOS:SLOT-VALUE-USING-CLASS returns the value
contained in the given slot of the given object. If the slot is
unbound, SLOT-UNBOUND is called.
The results are undefined if
the class argument is not the class of the object argument, or
if the slot argument does not appear among the set of effective
slots associated with the class argument.
Methods
(CLOS:SLOT-VALUE-USING-CLASS
(class STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))(CLOS:SLOT-VALUE-USING-CLASS
(class CLOS:FUNCALLABLE-STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))These methods implement
the full behavior of this generic function for slots with allocation
:INSTANCE and :CLASS. If the supplied slot has an allocation
other than :INSTANCE or :CLASS an ERROR is SIGNALed.
Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.
(CLOS:SLOT-VALUE-USING-CLASS
(class BUILT-IN-CLASS) object slot)SIGNALs an ERROR.
(SETF CLOS:SLOT-VALUE-USING-CLASS)((SETF CLOS:SLOT-VALUE-USING-CLASS) new-value class
object slot)new-valueclassobject argument.objectslotnew-value argument.The generic function (SETF CLOS:SLOT-VALUE-USING-CLASS) implements
the behavior of the ( function. It is called by
SETF SLOT-VALUE)( with the class of SETF SLOT-VALUE)object as its second argument
and the pertinent effective slot definition metaobject as its fourth argument.
The generic function (SETF CLOS:SLOT-VALUE-USING-CLASS) sets the value
contained in the given slot of the given object to the given new
value; any previous value is lost.
The results are undefined if
the class argument is not the class of the object argument, or
if the slot argument does not appear among the set of effective
slots associated with the class argument.
Methods
((SETF CLOS:SLOT-VALUE-USING-CLASS)
new-value (class STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))((SETF CLOS:SLOT-VALUE-USING-CLASS)
new-value (class CLOS:FUNCALLABLE-STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))These methods implement
the full behavior of this generic function for slots with allocation
:INSTANCE and :CLASS. If the supplied slot has an allocation
other than :INSTANCE or :CLASS an ERROR is SIGNALed.
Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.
((SETF CLOS:SLOT-VALUE-USING-CLASS)
new-value (class BUILT-IN-CLASS) object slot)SIGNALs an ERROR.
CLOS:SLOT-BOUNDP-USING-CLASS(CLOS:SLOT-BOUNDP-USING-CLASS class object
slot)classobject argument.objectslotBOOLEANThis generic function implements the behavior of the
SLOT-BOUNDP function. It is called by SLOT-BOUNDP with the class
of object as its first argument and the pertinent effective slot definition metaobject as its
third argument.
The generic function CLOS:SLOT-BOUNDP-USING-CLASS tests whether a
specific slot in an instance is bound.
The results are undefined if
the class argument is not the class of the object argument, or
if the slot argument does not appear among the set of effective
slots associated with the class argument.
Methods
(CLOS:SLOT-BOUNDP-USING-CLASS
(class STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))(CLOS:SLOT-BOUNDP-USING-CLASS
(class CLOS:FUNCALLABLE-STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))These methods implement
the full behavior of this generic function for slots with allocation
:INSTANCE and :CLASS. If the supplied slot has an allocation
other than :INSTANCE or :CLASS an ERROR is SIGNALed.
Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.
(CLOS:SLOT-BOUNDP-USING-CLASS
(class BUILT-IN-CLASS) object slot)SIGNALs an ERROR.Remarks. In cases where the class metaobject class does not distinguish unbound slots, true should be returned.
CLOS:SLOT-MAKUNBOUND-USING-CLASS(CLOS:SLOT-MAKUNBOUND-USING-CLASS class object
slot)classobject argument.objectslotobject argument.This generic function implements the behavior of the
SLOT-MAKUNBOUND function. It is called by SLOT-MAKUNBOUND with
the class of object as its first argument and the pertinent
effective slot definition metaobject as its third argument.
The generic function CLOS:SLOT-MAKUNBOUND-USING-CLASS restores a slot in
an object to its unbound state. The interpretation
of “restoring a slot to its unbound state” depends on
the class metaobject class.
The results are undefined if
the class argument is not the class of the object argument, or
if the slot argument does not appear among the set of effective
slots associated with the class argument.
Methods
(CLOS:SLOT-MAKUNBOUND-USING-CLASS
(class STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))(CLOS:SLOT-MAKUNBOUND-USING-CLASS
(class CLOS:FUNCALLABLE-STANDARD-CLASS) object
(slot CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION))These methods implement
the full behavior of this generic function for slots with allocation
:INSTANCE and :CLASS. If the supplied slot has an allocation
other than :INSTANCE or :CLASS an ERROR is SIGNALed.
Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.
(CLOS:SLOT-MAKUNBOUND-USING-CLASS
(class BUILT-IN-CLASS) object slot)SIGNALs an ERROR.
| These notes document CLISP version 2.49 | Last modified: 2010-07-07 |