10 |
|
|
11 |
@menu |
@menu |
12 |
* Equality:: When are two values `the same'? |
* Equality:: When are two values `the same'? |
13 |
* Property Lists:: Managing meta-information about Scheme objects. |
* Object Properties:: A modern interface to object properties. |
|
* Primitive Properties:: A modern interface to object properties. |
|
14 |
* Sorting:: Sort utility procedures. |
* Sorting:: Sort utility procedures. |
15 |
* Copying:: Copying deep structures. |
* Copying:: Copying deep structures. |
16 |
* General Conversion:: Converting objects to strings. |
* General Conversion:: Converting objects to strings. |
74 |
@end deffn |
@end deffn |
75 |
|
|
76 |
|
|
77 |
@node Property Lists |
@node Object Properties |
78 |
@section Property Lists |
@section Object Properties |
79 |
|
|
80 |
Every object in the system can have a @dfn{property list} that may |
It's often useful to associate a piece of additional information with a |
81 |
be used for information about that object. For example, a |
Scheme object even though that object does not have a dedicated slot |
82 |
function may have a property list that includes information about |
available in which the additional information could be stored. Object |
83 |
the source file in which it is defined. |
properties allow you to do just that. |
84 |
|
|
85 |
Property lists are implemented as assq lists (@pxref{Association Lists}). |
An object property is most commonly used to associate one kind of |
86 |
|
additional information with each instance of a class of similar Scheme |
87 |
Currently, property lists are implemented differently for procedures and |
objects. For example, all procedures have a `name' property, which |
88 |
closures than for other kinds of objects. Therefore, when manipulating |
stores the name of the variable in which the procedure was stored by a |
89 |
a property list associated with a procedure object, use the |
@code{define} expression, or @code{#f} if the procedure wasn't created |
90 |
@code{procedure} functions; otherwise, use the @code{object} functions. |
by that kind of expression. |
91 |
|
|
92 |
|
Guile's representation of an object property is a procedure-with-setter |
93 |
|
(@pxref{Procedures with Setters}) that can be used with the generalized |
94 |
|
form of @code{set!} (REFFIXME) to set and retrieve that property for any |
95 |
|
Scheme object. So, setting a property looks like this: |
96 |
|
|
97 |
@deffn {Scheme Procedure} object-properties obj |
@lisp |
98 |
@deffnx {C Function} scm_object_properties (obj) |
(set! (my-property obj1) value-for-obj1) |
99 |
Return @var{obj}'s property list. |
(set! (my-property obj2) value-for-obj2) |
100 |
@end deffn |
@end lisp |
101 |
|
|
102 |
@deffn {Scheme Procedure} set-object-properties! obj alist |
@noindent |
103 |
@deffnx {C Function} scm_set_object_properties_x (obj, alist) |
And retrieving values of the same property looks like this: |
|
Set @var{obj}'s property list to @var{alist}. |
|
|
@end deffn |
|
104 |
|
|
105 |
@deffn {Scheme Procedure} object-property obj key |
@lisp |
106 |
@deffnx {C Function} scm_object_property (obj, key) |
(my-property obj1) |
107 |
Return the property of @var{obj} with name @var{key}. |
@result{} |
108 |
@end deffn |
value-for-obj1 |
109 |
|
|
110 |
|
(my-property obj2) |
111 |
|
@result{} |
112 |
|
value-for-obj2 |
113 |
|
@end lisp |
114 |
|
|
115 |
@deffn {Scheme Procedure} set-object-property! obj key value |
To create an object property in the first place, use the |
116 |
@deffnx {C Function} scm_set_object_property_x (obj, key, value) |
@code{make-object-property} procedure: |
117 |
In @var{obj}'s property list, set the property named @var{key} |
|
118 |
to @var{value}. |
@lisp |
119 |
@end deffn |
(define my-property (make-object-property)) |
120 |
|
@end lisp |
121 |
|
|
122 |
[Interface bug: there should be a second level of interface in which |
@deffn {Scheme Procedure} make-object-property |
123 |
the user provides a "property table" that is possibly private.] |
Create and return an object property. An object property is a |
124 |
|
procedure-with-setter that can be called in two ways. @code{(set! |
125 |
|
(@var{property} @var{obj}) @var{val})} sets @var{obj}'s @var{property} |
126 |
|
to @var{val}. @code{(@var{property} @var{obj})} returns the current |
127 |
|
setting of @var{obj}'s @var{property}. |
128 |
|
@end deffn |
129 |
|
|
130 |
|
A single object property created by @code{make-object-property} can |
131 |
|
associate distinct property values with all Scheme values that are |
132 |
|
distinguishable by @code{eq?} (including, for example, integers). |
133 |
|
|
134 |
|
Internally, object properties are implemented using a weak key hash |
135 |
|
table. This means that, as long as a Scheme value with property values |
136 |
|
is protected from garbage collection, its property values are also |
137 |
|
protected. When the Scheme value is collected, its entry in the |
138 |
|
property table is removed and so the (ex-) property values are no longer |
139 |
|
protected by the table. |
140 |
|
|
141 |
|
@menu |
142 |
|
* Property Primitives:: Low level property implementation. |
143 |
|
* Old-fashioned Properties:: An older approach to properties. |
144 |
|
@end menu |
145 |
|
|
146 |
@node Primitive Properties |
|
147 |
@section Primitive Properties |
@node Property Primitives |
148 |
|
@subsection Low Level Property Implementation. |
149 |
|
|
150 |
@deffn {Scheme Procedure} primitive-make-property not_found_proc |
@deffn {Scheme Procedure} primitive-make-property not_found_proc |
151 |
@deffnx {C Function} scm_primitive_make_property (not_found_proc) |
@deffnx {C Function} scm_primitive_make_property (not_found_proc) |
177 |
@end deffn |
@end deffn |
178 |
|
|
179 |
|
|
180 |
|
@node Old-fashioned Properties |
181 |
|
@subsection An Older Approach to Properties |
182 |
|
|
183 |
|
Traditionally, Lisp systems provide a different object property |
184 |
|
interface to that provided by @code{make-object-property}, in which the |
185 |
|
object property that is being set or retrieved is indicated by a symbol. |
186 |
|
|
187 |
|
Guile includes this older kind of interface as well, but it may well be |
188 |
|
removed in a future release, as it is less powerful than |
189 |
|
@code{make-object-property} and so increases the size of the Guile |
190 |
|
library for no benefit. (And it is trivial to write a compatibility |
191 |
|
layer in Scheme.) |
192 |
|
|
193 |
|
@deffn {Scheme Procedure} object-properties obj |
194 |
|
@deffnx {C Function} scm_object_properties (obj) |
195 |
|
Return @var{obj}'s property list. |
196 |
|
@end deffn |
197 |
|
|
198 |
|
@deffn {Scheme Procedure} set-object-properties! obj alist |
199 |
|
@deffnx {C Function} scm_set_object_properties_x (obj, alist) |
200 |
|
Set @var{obj}'s property list to @var{alist}. |
201 |
|
@end deffn |
202 |
|
|
203 |
|
@deffn {Scheme Procedure} object-property obj key |
204 |
|
@deffnx {C Function} scm_object_property (obj, key) |
205 |
|
Return the property of @var{obj} with name @var{key}. |
206 |
|
@end deffn |
207 |
|
|
208 |
|
@deffn {Scheme Procedure} set-object-property! obj key value |
209 |
|
@deffnx {C Function} scm_set_object_property_x (obj, key, value) |
210 |
|
In @var{obj}'s property list, set the property named @var{key} |
211 |
|
to @var{value}. |
212 |
|
@end deffn |
213 |
|
|
214 |
|
|
215 |
@node Sorting |
@node Sorting |
216 |
@section Sorting |
@section Sorting |
217 |
|
|
413 |
using @code{run-hook}. |
using @code{run-hook}. |
414 |
|
|
415 |
@lisp |
@lisp |
416 |
(add-hook! hook (lambda (x y) |
(add-hook! hook (lambda (x y) |
417 |
(display "Foo: ") |
(display "Foo: ") |
418 |
(display (+ x y)) |
(display (+ x y)) |
419 |
(newline))) |
(newline))) |
420 |
(add-hook! hook (lambda (x y) |
(add-hook! hook (lambda (x y) |
421 |
(display "Bar: ") |
(display "Bar: ") |
422 |
(display (* x y)) |
(display (* x y)) |
423 |
(newline))) |
(newline))) |
424 |
(run-hook hook 3 4) |
(run-hook hook 3 4) |
425 |
@print{} Bar: 12 |
@print{} Bar: 12 |
431 |
on the second call to @code{add-hook!}. |
on the second call to @code{add-hook!}. |
432 |
|
|
433 |
@lisp |
@lisp |
434 |
(add-hook! hook (lambda (x y) |
(add-hook! hook (lambda (x y) |
435 |
(display "Foo: ") |
(display "Foo: ") |
436 |
(display (+ x y)) |
(display (+ x y)) |
437 |
(newline))) |
(newline))) |
438 |
(add-hook! hook (lambda (x y) |
(add-hook! hook (lambda (x y) |
439 |
(display "Bar: ") |
(display "Bar: ") |
440 |
(display (* x y)) |
(display (* x y)) |
441 |
(newline)) |
(newline)) |
442 |
#t) ; @r{<- Change here!} |
#t) ; @r{<- Change here!} |
443 |
(run-hook hook 3 4) |
(run-hook hook 3 4) |
444 |
@print{} Foo: 7 |
@print{} Foo: 7 |