|
|
|
|
home / intro / faq / tutorial / manual / models / download / people / about |
||
| property and method fields |
|
properties Properties, like identity fields, are storage locations. Unlike identity fields, however, the find/create behavior of the object constructor does not depend on the value of a property field; as a result, property fields may be changed.
There are two ways to define properties. Examples are shown in the code block below. The shorthand approach is to add &property to the end of the DEFCON form's concept lambda list followed by symbols naming the properties.
The long-hand way is to use the DEFPROP macro. This second method is more flexible, since the definition of properties can be given separately from the definition of the class. Under the hood, the &property lambda list keyword generates a DEFPROP form for you. Note, that if you use the &property keyword, you will not be able to define any identity fields after this point.
| properties | |||||||||
|
B-USER 1> (defcon x () (a
&property p)) ; shorthand
for defining a property {x :# #<concept-class x 2067F8FC>} B-USER 2> {[x 100].p := 10} ; set value (new) [x 100] 100 B-USER 3> [x 100].p ; get value 10 B-USER 4> [[x 100] :p 10] ; alternate syntax 1 [x 100] B-USER 5> [[x 100] {.p := 10}] ; alternate syntax 2 [x 100] B-USER 6> (defprop x.q ()) ; long hand definition X.Q B-USER 7> {[[x 100] :q 2] = [[x 100] :q 1]} ; these objects are the same! T B-USER 8> [x 100].q 1 |
|||||||||
methods Method fields allow arbitrary code to be run as a result of evaluating or setting a field. Like properties, method fields may be defined either using a concept lambda list keyword, &method, or using a long-hand form, the DEFIELD macro. Methods are functions specific to all instances of a class.
Within the body of DEFIELD, it is possible to refer to the specific object for which method has been invoked with the symbol OBJECT. Fields may be accessed with symbols beginning with a dot. Inside the DEFIELD forms below, defined for class X, the .A, .P and .Q symbols access the fields of X objects.
| methods | |||||||||
|
B-USER 9> (defield x.add-all
() {.a + .p + .q}) ; define
the function X.ADD-ALL B-USER 10> [x 100].add-all ; call the function (a=100,p=10,q=1) 111 B-USER 11> (defield x.p/a-ratio () {.p / .a}) X.P/A-RATIO B-USER 12> [x 100].p/a-ratio 1/10 B-USER 13> (defield (setf x.p/a-ratio) (value) ; define SETF method {.p := .a * value}) (SETF X.P/A-RATIO) B-USER 14> {[x 100].p/a-ratio := 4} ; setting the ratio implicitly sets p 4 B-USER 15> [x 100].p 400 B-USER 16> (defield x.find-field-by-value (o) ; a method with one argument (if {.a = o} :A (if {.p = o} :P (if {.q = o} :Q)))) X.FIND-FIELD-BY-VALUE B-USER 17> [x 100].(find-field-by-value 1) :Q B-USER 18> (defield x.?field (&rest args) ; the default field (format nil "Field ~A called with arguments ~S in object ~S.~%" ?field args object)) X.?FIELD B-USER 19> [x 100].(abc 1 2 3) "Field ABC called with arguments (1 2 3) in object [x 100]." |
|||||||||
In the above example, a field method, .ADD-ALL is defined which adds up all the storage fields of X. It could alternatively be defined in the class definition by writing:
| (defcon x () (a &property p q &method (add-all () {.a + .p + .q}))) |
Method fields, like property fields, do not affect the identity of an object. Accordingly, they may be changed - using either a SETF form or the := assignment operator (which is simply a shorthand for SETF). That is, (SETF object.field value) has the same effect as {object.field := value}.
Method fields may take arguments, which are defined in the second argument of the DEFIELD form. Standard lambda list keywords (&optional, &key, and &rest) are permitted. Calling methods with arguments involves writing dot syntax with parentheses. In the example, the FIND-FIELD-BY-VALUE field is invoked with argument 1 using [x 100].(find-field-by-value 1).
Default field methods are invoked when no other identity, property or method field is defined. They are defined using DEFIELD by writing CLASS-NAME.?FIELD for the method name. In the body of the method, the variable ?FIELD holds the value of the field.
naming objects
|