X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2FDEVEL%2Fpxp%2Fpxp%2Fdoc%2Fmanual%2Fhtml%2Fx1439.html;fp=helm%2FDEVEL%2Fpxp%2Fpxp%2Fdoc%2Fmanual%2Fhtml%2Fx1439.html;h=0000000000000000000000000000000000000000;hb=c7514aaa249a96c5fdd39b1123fbdb38d92f20b6;hp=26773057472438634725337ac1d3b979822fe8f5;hpb=1c7fb836e2af4f2f3d18afd0396701f2094265ff;p=helm.git diff --git a/helm/DEVEL/pxp/pxp/doc/manual/html/x1439.html b/helm/DEVEL/pxp/pxp/doc/manual/html/x1439.html deleted file mode 100644 index 267730574..000000000 --- a/helm/DEVEL/pxp/pxp/doc/manual/html/x1439.html +++ /dev/null @@ -1,464 +0,0 @@ -The class type extension
The PXP user's guide
PrevChapter 3. The objects representing the documentNext

3.3. The class type extension

class type [ 'node ] extension =
-  object ('self)
-    method clone : 'self
-      (* "clone" should return an exact deep copy of the object. *)
-    method node : 'node
-      (* "node" returns the corresponding node of this extension. This method
-       * intended to return exactly what previously has been set by "set_node".
-       *)
-    method set_node : 'node -> unit
-      (* "set_node" is invoked once the extension is associated to a new
-       * node object.
-       *)
-  end
- -This is the type of classes used for node extensions. For every node of the -document tree, there is not only the node object, but also -an extension object. The latter has minimal -functionality; it has only the necessary methods to be attached to the node -object containing the details of the node instance. The extension object is -called extension because its purpose is extensibility.

For some reasons, it is impossible to derive the -node classes (i.e. element_impl and -data_impl) such that the subclasses can be extended by new -new methods. But -subclassing nodes is a great feature, because it allows the user to provide -different classes for different types of nodes. The extension objects are a -workaround that is as powerful as direct subclassing, the costs are -some notation overhead.

Figure 3-6. The structure of nodes and extensions

The picture shows how the nodes and extensions are linked -together. Every node has a reference to its extension, and every extension has -a reference to its node. The methods extension and -node follow these references; a typical phrase is - -

self # node # attribute "xy"
- -to get the value of an attribute from a method defined in the extension object; -or - -
self # node # iter
-  (fun n -> n # extension # my_method ...)
- -to iterate over the subnodes and to call my_method of the -corresponding extension objects.

Note that extension objects do not have references to subnodes -(or "subextensions") themselves; in order to get one of the children of an -extension you must first go to the node object, then get the child node, and -finally reach the extension that is logically the child of the extension you -started with.

3.3.1. How to define an extension class

At minimum, you must define the methods -clone, node, and -set_node such that your class is compatible with the type -extension. The method set_node is called -during the initialization of the node, or after a node has been cloned; the -node object invokes set_node on the extension object to tell -it that this node is now the object the extension is linked to. The extension -must return the node object passed as argument of set_node -when the node method is called.

The clone method must return a copy of the -extension object; at least the object itself must be duplicated, but if -required, the copy should deeply duplicate all objects and values that are -referred by the extension, too. Whether this is required, depends on the -application; clone is invoked by the node object when one of -its cloning methods is called.

A good starting point for an extension class: - -

class custom_extension =
-  object (self)
-
-    val mutable node = (None : custom_extension node option)
-
-    method clone = {< >} 
-
-    method node =
-      match node with
-          None ->
-            assert false
-        | Some n -> n
-
-    method set_node n =
-      node <- Some n
-
-  end
- -This class is compatible with extension. The purpose of -defining such a class is, of course, adding further methods; and you can do it -without restriction.

Often, you want not only one extension class. In this case, -it is the simplest way that all your classes (for one kind of document) have -the same type (with respect to the interface; i.e. it does not matter if your -classes differ in the defined private methods and instance variables, but -public methods count). This approach avoids lots of coercions and problems with -type incompatibilities. It is simple to implement: - -

class custom_extension =
-  object (self)
-    val mutable node = (None : custom_extension node option)
-
-    method clone = ...      (* see above *)
-    method node = ...       (* see above *)
-    method set_node n = ... (* see above *)
-
-    method virtual my_method1 : ...
-    method virtual my_method2 : ...
-    ... (* etc. *)
-  end
-
-class custom_extension_kind_A =
-  object (self)
-    inherit custom_extension
-
-    method my_method1 = ...
-    method my_method2 = ...
-  end
-
-class custom_extension_kind_B =
-  object (self)
-    inherit custom_extension
-
-    method my_method1 = ...
-    method my_method2 = ...
-  end
- -If a class does not need a method (e.g. because it does not make sense, or it -would violate some important condition), it is possible to define the method -and to always raise an exception when the method is invoked -(e.g. assert false).

The latter is a strong recommendation: do not try to further -specialize the types of extension objects. It is difficult, sometimes even -impossible, and almost never worth-while.

3.3.2. How to bind extension classes to element types

Once you have defined your extension classes, you can bind them -to element types. The simplest case is that you have only one class and that -this class is to be always used. The parsing functions in the module -Pxp_yacc take a spec argument which -can be customized. If your single class has the name c, -this argument should be - -

let spec =
-  make_spec_from_alist
-    ~data_exemplar:            (new data_impl c)
-    ~default_element_exemplar: (new element_impl c)
-    ~element_alist:            []
-    ()
- -This means that data nodes will be created from the exemplar passed by -~data_exemplar and that all element nodes will be made from the exemplar -specified by ~default_element_exemplar. In ~element_alist, you can -pass that different exemplars are to be used for different element types; but -this is an optional feature. If you do not need it, pass the empty list.

Remember that an exemplar is a (node, extension) pair that serves as pattern -when new nodes (and the corresponding extension objects) are added to the -document tree. In this case, the exemplar contains c as -extension, and when nodes are created, the exemplar is cloned, and cloning -makes also a copy of c such that all nodes of the document -tree will have a copy of c as extension.

The ~element_alist argument can bind -specific element types to specific exemplars; as exemplars may be instances of -different classes it is effectively possible to bind element types to -classes. For example, if the element type "p" is implemented by class "c_p", -and "q" is realized by "c_q", you can pass the following value: - -

let spec =
-  make_spec_from_alist
-    ~data_exemplar:            (new data_impl c)
-    ~default_element_exemplar: (new element_impl c)
-    ~element_alist:            
-      [ "p", new element_impl c_p;
-        "q", new element_impl c_q;
-      ]
-    ()
- -The extension object c is still used for all data nodes and -for all other element types.


PrevHomeNext
The class type nodeUpDetails of the mapping from XML text to the tree representation
\ No newline at end of file