User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:macros:with-slots [2019/12/05 03:00]
cl:macros:with-slots [2019/12/15 06:00] (current)
Line 1: Line 1:
 +====== Macro WITH-SLOTS ======
 +
 +====Syntax====
 +  * **with-slots** (//​slot-entry//''​*''​) //​instance-form//​ //​declaration''​*''//​ //​form''​*''//​ → //​result''​*''//​
 +
 +<​blockquote>​
 +slot-entry ::= //​slot-name//​ | (//​variable-name//​ //​slot-name//​)
 +</​blockquote>​
 +
 +====Arguments and Values====
 +  * //​slot-name//​ - a //​[[CL:​Glossary:​slot]]//​ //​[[CL:​Glossary:​name]]//;​ not evaluated.
 +  * //​variable-name//​ - a //​[[CL:​Glossary:​variable name]]//; not evaluated.
 +  * //​instance-form//​ - a //​[[CL:​Glossary:​form]]//;​ evaluted to produce //​instance//​.
 +  * //​instance//​ - an //​[[CL:​Glossary:​object]]//​.
 +  * //​declaration//​ - a **[[CL:​Symbols:​declare]]** //​[[CL:​Glossary:​expression]]//;​ not evaluated.
 +  * //forms// - an //​[[CL:​Glossary:​implicit progn]]//.
 +  * //results// - the //​[[CL:​Glossary:​values]]//​ returned by the //forms//.
 +
 +====Description====
 +The macro **with-slots** //​[[CL:​Glossary:​establishes]]//​ a //​[[CL:​Glossary:​lexical environment]]//​ for referring to the //​[[CL:​Glossary:​slot|slots]]//​ in the //​instance//​ named by the given //​slot-names//​ as though they were //​[[CL:​Glossary:​variables]]//​. Within such a context the value of the //​[[CL:​Glossary:​slot]]//​ can be specified by using its slot name, as if it were a lexically bound variable. Both **[[CL:​Macros:​setf]]** and **[[CL:​Special Operators:​setq]]** can be used to set the value of the //​[[CL:​Glossary:​slot]]//​.
 +
 +The macro **with-slots** translates an appearance of the slot name as a //​[[CL:​Glossary:​variable]]//​ into a call to **[[CL:​Functions:​slot-value]]**.
 +
 +====Examples====
 +<​blockquote> ​
 +([[CL:​Macros:​defclass]] thing () 
 +  ((x :initarg :x :accessor thing-x) ​
 +   (y :initarg :y :accessor thing-y))) <​r>#<​STANDARD-CLASS THING 250020173>​ </r>
 +([[CL:​Macros:​defmethod]] ([[CL:​Macros:​setf]] thing-x) :before (new-x (thing thing)) ​
 +  ([[CL:​Functions:​format]] [[CL:​Constant Variables:​t]] "​~&​Changing X from ~D to ~D in ~S.~%" ​
 +          (thing-x thing) new-x thing))
 +([[CL:​Macros:​defparameter]] thing ([[CL:​Functions:​make-instance]] 'thing :x 0 :y 1)) <​r>#<​THING 62310540>​ </r>
 +(with-slots (x y) thing 
 +  ([[CL:​Macros:​incf]] x) 
 +  ([[CL:​Macros:​incf]] y)) <r>2 </r>
 +(values (thing-x thing) (thing-y thing)) <r>1, 2 </r>
 +([[CL:​Macros:​defparameter]] thing1 ([[CL:​Functions:​make-instance]] 'thing :x 1 :y 2)) <​r>#<​THING 43135676>​ </r>
 +([[CL:​Macros:​defparameter]] thing2 ([[CL:​Functions:​make-instance]] 'thing :x 7 :y 8)) <​r>#<​THING 43147374>​ </r>
 +(with-slots ((x1 x) (y1 y)) thing1 ​
 +  (with-slots ((x2 x) (y2 y)) thing2 ​
 +    ([[CL:​Functions:​list]] ([[CL:​Functions:​list]] x1 (thing-x thing1) y1 (thing-y thing1) ​
 +                x2 (thing-x thing2) y2 (thing-y thing2)) ​
 +          ([[CL:​Macros:​setf]] x1 ([[CL:​Functions:​math-add|+]] y1 x2)) 
 +          ([[CL:​Functions:​list]] x1 (thing-x thing1) y1 (thing-y thing1) ​
 +                x2 (thing-x thing2) y2 (thing-y thing2)) ​
 +          ([[CL:​Macros:​setf]] (thing-x thing2) ([[CL:​Functions:​list]] x1)) 
 +          ([[CL:​Functions:​list]] x1 (thing-x thing1) y1 (thing-y thing1) ​
 +                x2 (thing-x thing2) y2 (thing-y thing2)))))
 +<​o>​Changing X from 7 to (9) in #<THING 43147374>​. </o>
 +<​r>​((1 1 2 2 7 7 8 8) 9 (9 9 2 2 7 7 8 8) (9) (9 9 2 2 (9) (9) 8 8))</​r>​
 +</​blockquote>​
 +
 +====Affected By====
 +**[[CL:​Macros:​defclass]]**
 +
 +====Exceptional Situations====
 +The consequences are undefined if any //​slot-name//​ is not the name of a //​[[CL:​Glossary:​slot]]//​ in the //​instance//​.
 +
 +====See Also====
 +  * **[[CL:​Macros:​with-accessors|Macro WITH-ACCESSORS]]**
 +  * **[[CL:​Functions:​slot-value|Function SLOT-VALUE]]**
 +  * **[[CL:​Special Operators:​symbol-macrolet]]**
 +
 +====Notes====
 +A **with-slots** expression of the form:
 +
 +<​blockquote>​
 +(with-slots (//​slot-entry<​sub>​1</​sub>//​ ... //​slot-entry<​sub>​n</​sub>//​) //​instance-form//​
 +  //​form<​sub>​1</​sub>//​
 +  ...
 +  //​form<​sub>​n</​sub>//​
 +</​blockquote>​
 +
 +expands into the equivalent of:
 +
 +<​blockquote>​
 +(let ((in //​instance-form//​))
 +  (symbol-macrolet (//​Q<​sub>​1</​sub>//​ ... //​Q<​sub>​n</​sub>//​)
 +    //​form<​sub>​1</​sub>// ​
 +    ... 
 +    //​form<​sub>​k</​sub>//​))
 +</​blockquote>​
 +
 +where Q<​sub>​i</​sub>,​ if //​slot-entry<​sub>​i</​sub>//​ is a //​[[CL:​Glossary:​symbol]]//,​ is:
 +
 +<​blockquote>​
 +(//​slot-entry<​sub>​i</​sub>//​ () ([[CL:​Functions:​slot-value]] in '//​slot-entry<​sub>​i</​sub>//​))
 +</​blockquote>​
 +
 +If //​slot-entry<​sub>​i</​sub>//​ is of the form ''​(//​variable-name<​sub>​i</​sub>//​ //​slot-name<​sub>​i</​sub>//​))'',​ then Q<​sub>​i</​sub>​ is:
 +
 +<​blockquote>​
 +(//​variable-name<​sub>​i</​sub>//​ () ([[CL:​Functions:​slot-value]] in '//​slot-name<​sub>​i</​sub>//​))
 +</​blockquote>​
 +
 +\issue{DECLS-AND-DOC}