]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/pxp/pxp/doc/manual/html/x1439.html
- the mathql interpreter is not helm-dependent any more
[helm.git] / helm / DEVEL / pxp / pxp / doc / manual / html / x1439.html
1 <HTML
2 ><HEAD
3 ><TITLE
4 >The class type extension</TITLE
5 ><META
6 NAME="GENERATOR"
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.46"><LINK
8 REL="HOME"
9 TITLE="The PXP user's guide"
10 HREF="index.html"><LINK
11 REL="UP"
12 TITLE="The objects representing the document"
13 HREF="c893.html"><LINK
14 REL="PREVIOUS"
15 TITLE="The class type node"
16 HREF="x939.html"><LINK
17 REL="NEXT"
18 TITLE="Details of the mapping from XML text to the tree representation"
19 HREF="x1496.html"><LINK
20 REL="STYLESHEET"
21 TYPE="text/css"
22 HREF="markup.css"></HEAD
23 ><BODY
24 CLASS="SECT1"
25 BGCOLOR="#FFFFFF"
26 TEXT="#000000"
27 LINK="#0000FF"
28 VLINK="#840084"
29 ALINK="#0000FF"
30 ><DIV
31 CLASS="NAVHEADER"
32 ><TABLE
33 WIDTH="100%"
34 BORDER="0"
35 CELLPADDING="0"
36 CELLSPACING="0"
37 ><TR
38 ><TH
39 COLSPAN="3"
40 ALIGN="center"
41 >The PXP user's guide</TH
42 ></TR
43 ><TR
44 ><TD
45 WIDTH="10%"
46 ALIGN="left"
47 VALIGN="bottom"
48 ><A
49 HREF="x939.html"
50 >Prev</A
51 ></TD
52 ><TD
53 WIDTH="80%"
54 ALIGN="center"
55 VALIGN="bottom"
56 >Chapter 3. The objects representing the document</TD
57 ><TD
58 WIDTH="10%"
59 ALIGN="right"
60 VALIGN="bottom"
61 ><A
62 HREF="x1496.html"
63 >Next</A
64 ></TD
65 ></TR
66 ></TABLE
67 ><HR
68 ALIGN="LEFT"
69 WIDTH="100%"></DIV
70 ><DIV
71 CLASS="SECT1"
72 ><H1
73 CLASS="SECT1"
74 ><A
75 NAME="AEN1439"
76 >3.3. The class type <TT
77 CLASS="LITERAL"
78 >extension</TT
79 ></A
80 ></H1
81 ><P
82 >&#13;<PRE
83 CLASS="PROGRAMLISTING"
84 >class type [ 'node ] extension =
85   object ('self)
86     method clone : 'self
87       (* "clone" should return an exact deep copy of the object. *)
88     method node : 'node
89       (* "node" returns the corresponding node of this extension. This method
90        * intended to return exactly what previously has been set by "set_node".
91        *)
92     method set_node : 'node -&#62; unit
93       (* "set_node" is invoked once the extension is associated to a new
94        * node object.
95        *)
96   end</PRE
97 >
98
99 This is the type of classes used for node extensions. For every node of the
100 document tree, there is not only the <TT
101 CLASS="LITERAL"
102 >node</TT
103 > object, but also
104 an <TT
105 CLASS="LITERAL"
106 >extension</TT
107 > object. The latter has minimal
108 functionality; it has only the necessary methods to be attached to the node
109 object containing the details of the node instance. The extension object is
110 called extension because its purpose is extensibility.</P
111 ><P
112 >For some reasons, it is impossible to derive the
113 <TT
114 CLASS="LITERAL"
115 >node</TT
116 > classes (i.e. <TT
117 CLASS="LITERAL"
118 >element_impl</TT
119 > and
120 <TT
121 CLASS="LITERAL"
122 >data_impl</TT
123 >) such that the subclasses can be extended by new
124 new methods. But
125 subclassing nodes is a great feature, because it allows the user to provide
126 different classes for different types of nodes. The extension objects are a
127 workaround that is as powerful as direct subclassing, the costs are
128 some notation overhead.</P
129 ><DIV
130 CLASS="FIGURE"
131 ><A
132 NAME="EXTENSION-GENERAL"
133 ></A
134 ><P
135 ><B
136 >Figure 3-6. The structure of nodes and extensions</B
137 ></P
138 ><P
139 ><IMG
140 SRC="pic/extension_general.gif"></P
141 ></DIV
142 ><P
143 >The picture shows how the nodes and extensions are linked
144 together. Every node has a reference to its extension, and every extension has
145 a reference to its node. The methods <TT
146 CLASS="LITERAL"
147 >extension</TT
148 > and
149 <TT
150 CLASS="LITERAL"
151 >node</TT
152 > follow these references; a typical phrase is 
153
154 <PRE
155 CLASS="PROGRAMLISTING"
156 >self # node # attribute "xy"</PRE
157 >
158
159 to get the value of an attribute from a method defined in the extension object;
160 or 
161
162 <PRE
163 CLASS="PROGRAMLISTING"
164 >self # node # iter
165   (fun n -&gt; n # extension # my_method ...)</PRE
166 >
167
168 to iterate over the subnodes and to call <TT
169 CLASS="LITERAL"
170 >my_method</TT
171 > of the
172 corresponding extension objects.</P
173 ><P
174 >Note that extension objects do not have references to subnodes
175 (or "subextensions") themselves; in order to get one of the children of an
176 extension you must first go to the node object, then get the child node, and
177 finally reach the extension that is logically the child of the extension you
178 started with.</P
179 ><DIV
180 CLASS="SECT2"
181 ><H2
182 CLASS="SECT2"
183 ><A
184 NAME="AEN1460"
185 >3.3.1. How to define an extension class</A
186 ></H2
187 ><P
188 >At minimum, you must define the methods
189 <TT
190 CLASS="LITERAL"
191 >clone</TT
192 >, <TT
193 CLASS="LITERAL"
194 >node</TT
195 >, and
196 <TT
197 CLASS="LITERAL"
198 >set_node</TT
199 > such that your class is compatible with the type
200 <TT
201 CLASS="LITERAL"
202 >extension</TT
203 >. The method <TT
204 CLASS="LITERAL"
205 >set_node</TT
206 > is called
207 during the initialization of the node, or after a node has been cloned; the
208 node object invokes <TT
209 CLASS="LITERAL"
210 >set_node</TT
211 > on the extension object to tell
212 it that this node is now the object the extension is linked to. The extension
213 must return the node object passed as argument of <TT
214 CLASS="LITERAL"
215 >set_node</TT
216 >
217 when the <TT
218 CLASS="LITERAL"
219 >node</TT
220 > method is called.</P
221 ><P
222 >The <TT
223 CLASS="LITERAL"
224 >clone</TT
225 > method must return a copy of the
226 extension object; at least the object itself must be duplicated, but if
227 required, the copy should deeply duplicate all objects and values that are
228 referred by the extension, too. Whether this is required, depends on the
229 application; <TT
230 CLASS="LITERAL"
231 >clone</TT
232 > is invoked by the node object when one of
233 its cloning methods is called.</P
234 ><P
235 >A good starting point for an extension class:
236
237 <PRE
238 CLASS="PROGRAMLISTING"
239 >class custom_extension =
240   object (self)
241
242     val mutable node = (None : custom_extension node option)
243
244     method clone = {&#60; &#62;} 
245
246     method node =
247       match node with
248           None -&#62;
249             assert false
250         | Some n -&#62; n
251
252     method set_node n =
253       node &#60;- Some n
254
255   end</PRE
256 >
257
258 This class is compatible with <TT
259 CLASS="LITERAL"
260 >extension</TT
261 >. The purpose of
262 defining such a class is, of course, adding further methods; and you can do it
263 without restriction. </P
264 ><P
265 >Often, you want not only one extension class. In this case,
266 it is the simplest way that all your classes (for one kind of document) have
267 the same type (with respect to the interface; i.e. it does not matter if your
268 classes differ in the defined private methods and instance variables, but
269 public methods count). This approach avoids lots of coercions and problems with
270 type incompatibilities. It is simple to implement:
271
272 <PRE
273 CLASS="PROGRAMLISTING"
274 >class custom_extension =
275   object (self)
276     val mutable node = (None : custom_extension node option)
277
278     method clone = ...      (* see above *)
279     method node = ...       (* see above *)
280     method set_node n = ... (* see above *)
281
282     method virtual my_method1 : ...
283     method virtual my_method2 : ...
284     ... (* etc. *)
285   end
286
287 class custom_extension_kind_A =
288   object (self)
289     inherit custom_extension
290
291     method my_method1 = ...
292     method my_method2 = ...
293   end
294
295 class custom_extension_kind_B =
296   object (self)
297     inherit custom_extension
298
299     method my_method1 = ...
300     method my_method2 = ...
301   end</PRE
302 >
303
304 If a class does not need a method (e.g. because it does not make sense, or it
305 would violate some important condition), it is possible to define the method
306 and to always raise an exception when the method is invoked
307 (e.g. <TT
308 CLASS="LITERAL"
309 >assert false</TT
310 >).</P
311 ><P
312 >The latter is a strong recommendation: do not try to further
313 specialize the types of extension objects. It is difficult, sometimes even
314 impossible, and almost never worth-while.</P
315 ></DIV
316 ><DIV
317 CLASS="SECT2"
318 ><H2
319 CLASS="SECT2"
320 ><A
321 NAME="AEN1481"
322 >3.3.2. How to bind extension classes to element types</A
323 ></H2
324 ><P
325 >Once you have defined your extension classes, you can bind them
326 to element types. The simplest case is that you have only one class and that
327 this class is to be always used. The parsing functions in the module
328 <TT
329 CLASS="LITERAL"
330 >Pxp_yacc</TT
331 > take a <TT
332 CLASS="LITERAL"
333 >spec</TT
334 > argument which
335 can be customized. If your single class has the name <TT
336 CLASS="LITERAL"
337 >c</TT
338 >,
339 this argument should be 
340
341 <PRE
342 CLASS="PROGRAMLISTING"
343 >let spec =
344   make_spec_from_alist
345     ~data_exemplar:            (new data_impl c)
346     ~default_element_exemplar: (new element_impl c)
347     ~element_alist:            []
348     ()</PRE
349 >
350
351 This means that data nodes will be created from the exemplar passed by
352 ~data_exemplar and that all element nodes will be made from the exemplar
353 specified by ~default_element_exemplar. In ~element_alist, you can 
354 pass that different exemplars are to be used for different element types; but
355 this is an optional feature. If you do not need it, pass the empty list.</P
356 ><P
357 >Remember that an exemplar is a (node, extension) pair that serves as pattern
358 when new nodes (and the corresponding extension objects) are added to the
359 document tree. In this case, the exemplar contains <TT
360 CLASS="LITERAL"
361 >c</TT
362 > as
363 extension, and when nodes are created, the exemplar is cloned, and cloning
364 makes also a copy of <TT
365 CLASS="LITERAL"
366 >c</TT
367 > such that all nodes of the document
368 tree will have a copy of <TT
369 CLASS="LITERAL"
370 >c</TT
371 > as extension.</P
372 ><P
373 >The <TT
374 CLASS="LITERAL"
375 >~element_alist</TT
376 > argument can bind
377 specific element types to specific exemplars; as exemplars may be instances of
378 different classes it is effectively possible to bind element types to
379 classes. For example, if the element type "p" is implemented by class "c_p",
380 and "q" is realized by "c_q", you can pass the following value:
381
382 <PRE
383 CLASS="PROGRAMLISTING"
384 >let spec =
385   make_spec_from_alist
386     ~data_exemplar:            (new data_impl c)
387     ~default_element_exemplar: (new element_impl c)
388     ~element_alist:            
389       [ "p", new element_impl c_p;
390         "q", new element_impl c_q;
391       ]
392     ()</PRE
393 >
394
395 The extension object <TT
396 CLASS="LITERAL"
397 >c</TT
398 > is still used for all data nodes and
399 for all other element types.</P
400 ></DIV
401 ></DIV
402 ><DIV
403 CLASS="NAVFOOTER"
404 ><HR
405 ALIGN="LEFT"
406 WIDTH="100%"><TABLE
407 WIDTH="100%"
408 BORDER="0"
409 CELLPADDING="0"
410 CELLSPACING="0"
411 ><TR
412 ><TD
413 WIDTH="33%"
414 ALIGN="left"
415 VALIGN="top"
416 ><A
417 HREF="x939.html"
418 >Prev</A
419 ></TD
420 ><TD
421 WIDTH="34%"
422 ALIGN="center"
423 VALIGN="top"
424 ><A
425 HREF="index.html"
426 >Home</A
427 ></TD
428 ><TD
429 WIDTH="33%"
430 ALIGN="right"
431 VALIGN="top"
432 ><A
433 HREF="x1496.html"
434 >Next</A
435 ></TD
436 ></TR
437 ><TR
438 ><TD
439 WIDTH="33%"
440 ALIGN="left"
441 VALIGN="top"
442 >The class type <TT
443 CLASS="LITERAL"
444 >node</TT
445 ></TD
446 ><TD
447 WIDTH="34%"
448 ALIGN="center"
449 VALIGN="top"
450 ><A
451 HREF="c893.html"
452 >Up</A
453 ></TD
454 ><TD
455 WIDTH="33%"
456 ALIGN="right"
457 VALIGN="top"
458 >Details of the mapping from XML text to the tree representation</TD
459 ></TR
460 ></TABLE
461 ></DIV
462 ></BODY
463 ></HTML
464 >