Remains as defined in ANSI Common Lisp, but extra control over parsing of class options and slot options, optimization of slot access, and checking of initargs, is provided.
The macro
defclass
is as defined in the ANSI standard with the following extensions.
For extra class options, you may need to define the way these are parsed at
defclass
macroexpansion time. See process-a-class-option for details.
For non-standard slot options, you may need to define the way these are parsed at
defclass
macroexpansion time. See process-a-slot-option for details.
By default, standard slot accessors are optimized such that they do not call slot-value-using-class. This optimization can be switched off using the
:optimize-slot-access
nil
class option.
To add valid initialization arguments for the class, use the class option
:extra-initargs
. The argument passed via this option is evaluated, and should return a list of extra initialization arguments for the class. make-instance will treat these as valid when checking its arguments.
When a class is redefined, its extra initargs are always reset.
In early versions of LispWorks 4.3, extra initargs were not reset when a class was redefined without specifying extra initargs.
This session illustrates the effects of the
:optimize-slot-access
class option. When true, slot access is more efficient but note that slot-value-using-class is not called.
CL-USER 26 > (compile '(defclass foo ()
((a :type fixnum
:initarg :a
:reader foo-a))))
NIL
CL-USER 27 > (compile '(defclass bar ()
((a :type fixnum
:initarg :a
:reader bar-a))
(:optimize-slot-access nil)))
NIL
CL-USER 28 > (setf *foo*
(make-instance 'foo :a 42)
*bar* (make-instance 'bar :a 99))
#<BAR 21D33D4C>
CL-USER 29 > (progn
(time (dotimes (i 1000000)
(foo-a *foo*)))
(time (dotimes (i 1000000)
(bar-a *bar*))))
Timing the evaluation of (DOTIMES (I 1000000) (FOO-A *FOO*))
user time = 0.328
system time = 0.015
Elapsed time = 0:00:00
Allocation = 2280 bytes standard / 11002882 bytes conses
0 Page faults
Timing the evaluation of (DOTIMES (I 1000000) (BAR-A *BAR*))
user time = 0.406
system time = 0.015
Elapsed time = 0:00:00
Allocation = 4304 bytes standard / 11004521 bytes conses
0 Page faults
NIL
CL-USER 30 > (trace
(clos:slot-value-using-class
:when
(and (member (first *traced-arglist*)
(list (find-class 'foo)
(find-class 'bar)))
(eq (third *traced-arglist*) 'a))))
(CLOS:SLOT-VALUE-USING-CLASS)
CL-USER 31 > (foo-a *foo*)
42
CL-USER 32 > (bar-a *bar*)
0 CLOS:SLOT-VALUE-USING-CLASS > ...
>> CLASS : #<STANDARD-CLASS BAR 214897F4>
>> CLOS::OBJECT : #<BAR 2148820C>
>> CLOS::SLOT-NAME : A
0 CLOS:SLOT-VALUE-USING-CLASS < ...
<< VALUE-0 : 99
99
This session illustrates the
:extra-initargs
class option:
CL-USER 46 > (defclass a () ()
(:extra-initargs '(:a-initarg)))
#<STANDARD-CLASS A 21C2E4FC>
CL-USER 47 > (defclass b (a) ()
(:extra-initargs '(:b-initarg)))
#<STANDARD-CLASS B 2068573C>
CL-USER 48 > (defclass c (a) ())
#<STANDARD-CLASS C 22829D44>
CL-USER 49 > (make-instance 'b :a-initarg "A" :b-initarg "B")
#<B 2068BCE4>
CL-USER 50 > (make-instance 'c :a-initarg "A" :b-initarg "B")
Error: MAKE-INSTANCE is called with unknown keyword :B-INITARG among the arguments (C :A-INITARG "A" :B-INITARG "B") which is not one of (:A-INITARG).
1 (continue) Ignore the keyword :B-INITARG
2 (abort) Return to level 0.
3 Return to top loop level 0.
Type :b for backtrace, :c <option number> to proceed, or :? for other options
CL-USER 51 : 1 >