From de664683019ed4dbba048b44b3529b71daa198c0 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 28 Oct 2018 15:36:55 +0000 Subject: Documentation --- doc/define.n | 241 +++++++++++++++++++++++++++++++++++++++++------------------ doc/info.n | 18 +++++ 2 files changed, 187 insertions(+), 72 deletions(-) diff --git a/doc/define.n b/doc/define.n index 883d5fa..7be9e9b 100644 --- a/doc/define.n +++ b/doc/define.n @@ -34,7 +34,11 @@ either the \fIdefScript\fR argument or by the \fIsubcommand\fR and following \fIarg\fR arguments; when the second is present, it is exactly as if all the arguments from \fIsubcommand\fR onwards are made into a list and that list is used as the \fIdefScript\fR argument. -.SS "CONFIGURING CLASSES" +.PP +Note that the constructor for \fBoo::class\fR will call \fBoo::define\fR on +the script argument that it is provided. This is a convenient way to create +and define a class in one step. +.SH "CONFIGURING CLASSES" .PP The following commands are supported in the \fIdefScript\fR for \fBoo::define\fR, each of which may also be used in the \fIsubcommand\fR form: @@ -70,13 +74,11 @@ namespace of the constructor will be a namespace that is unique to the object being constructed. Within the constructor, the \fBnext\fR command should be used to call the superclasses' constructors. If \fIbodyScript\fR is the empty string, the constructor will be deleted. -.TP -\fBdeletemethod\fI name\fR ?\fIname ...\fR? -. -This deletes each of the methods called \fIname\fR from a class. The methods -must have previously existed in that class. Does not affect the superclasses -of the class, nor does it affect the subclasses or instances of the class -(except when they have a call chain through the class being modified). +.RS +.PP +Classes do not need to have a constructor defined. If none is specified, the +superclass's constructor will be used instead. +.RE .TP \fBdestructor\fI bodyScript\fR . @@ -102,16 +104,6 @@ class being defined. Note that the methods themselves may be actually defined by a superclass; subclass exports override superclass visibility, and may in turn be overridden by instances. .TP -\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR? -. -This slot (see \fBSLOTTED DEFINITIONS\fR below) -sets or updates the list of method names that are used to guard whether -method call to instances of the class may be called and what the method's -results are. Each \fImethodName\fR names a single filtering method (which may -be exposed or not exposed); it is not an error for a non-existent method to be -named since they may be defined by subclasses. -By default, this slot works by appending. -.TP \fBforward\fI name cmdName \fR?\fIarg ...\fR? . This creates or updates a forwarded method called \fIname\fR. The method is @@ -159,14 +151,6 @@ below), this command creates private procedure-like methods. .VE TIP500 .RE .TP -\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR? -. -This slot (see \fBSLOTTED DEFINITIONS\fR below) -sets or updates the list of additional classes that are to be mixed into -all the instances of the class being defined. Each \fIclassName\fR argument -names a single class that is to be mixed in. -By default, this slot works by replacement. -.TP \fBprivate \fIcmd arg...\fR .TP \fBprivate \fIscript\fR @@ -186,16 +170,6 @@ context. .RE .VE TIP500 .TP -\fBrenamemethod\fI fromName toName\fR -. -This renames the method called \fIfromName\fR in a class to \fItoName\fR. The -method must have previously existed in the class, and \fItoName\fR must not -previously refer to a method in that class. Does not affect the superclasses -of the class, nor does it affect the subclasses or instances of the class -(except when they have a call chain through the class being modified). Does -not change the export status of the method; if it was exported before, it will -be afterwards. -.TP \fBself\fI subcommand arg ...\fR .TP \fBself\fI script\fR @@ -269,23 +243,76 @@ namespace has a unique prefix that makes accidental use from other classes extremely unlikely. .VE TIP500 .RE -.SS "CONFIGURING OBJECTS" +.SS "ADVANCED CLASS CONFIGURATION OPTIONS" .PP -The following commands are supported in the \fIdefScript\fR for -\fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR -form: +The following definitions are also supported, but are not required in simple +programs: +.TP +\fBdefinitionnamespace\fR ?\fIkind\fR? \fInamespaceName\fR +.VS TIP524 +This allows control over what namespace will be used by the \fBoo::define\fR +and \fBoo::objdefine\fR commands to look up the definition commands they +use. When any object has a definition operation applied to it, \fIthe class that +it is an instance of\fR (and its superclasses and mixins) is consulted for +what definition namespace to use. \fBoo::define\fR gets the class definition +namespace, and \fB::oo::objdefine\fR gets the instance definition namespace, +but both otherwise use the identical lookup operation. +.RS +.PP +This sets the definition namespace of kind \fIkind\fR provided by the current +class to \fInamespaceName\fR. The \fInamespaceName\fR must refer to a +currently existing namespace, or must be the empty string (to stop the current +class from having such a namespace connected). The \fIkind\fR, if supplied, +must be either \fB\-class\fR (the default) or \fB\-instance\fR to specify the +whether the namespace for use with \fBoo::define\fR or \fBoo::objdefine\fR +respectively is being set. +.PP +The class \fBoo::object\fR has its instance namespace locked to +\fB::oo::objdefine\fR, and the class \fBoo::class\fR has its class namespace +locked to \fB::oo::define\fR. A consequence of this is that effective use of +this feature for classes requires the definition of a metaclass. +.RE +.VE TIP524 .TP -\fBclass\fI className\fR +\fBdeletemethod\fI name\fR ?\fIname ...\fR? . -This allows the class of an object to be changed after creation. Note that the -class's constructors are not called when this is done, and so the object may -well be in an inconsistent state unless additional configuration work is done. +This deletes each of the methods called \fIname\fR from a class. The methods +must have previously existed in that class. Does not affect the superclasses +of the class, nor does it affect the subclasses or instances of the class +(except when they have a call chain through the class being modified). .TP -\fBdeletemethod\fI name\fR ?\fIname ...\fR +\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR? . -This deletes each of the methods called \fIname\fR from an object. The methods -must have previously existed in that object. Does not affect the classes that -the object is an instance of. +This slot (see \fBSLOTTED DEFINITIONS\fR below) +sets or updates the list of method names that are used to guard whether +method call to instances of the class may be called and what the method's +results are. Each \fImethodName\fR names a single filtering method (which may +be exposed or not exposed); it is not an error for a non-existent method to be +named since they may be defined by subclasses. +By default, this slot works by appending. +.TP +\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR? +. +This slot (see \fBSLOTTED DEFINITIONS\fR below) +sets or updates the list of additional classes that are to be mixed into +all the instances of the class being defined. Each \fIclassName\fR argument +names a single class that is to be mixed in. +By default, this slot works by replacement. +.TP +\fBrenamemethod\fI fromName toName\fR +. +This renames the method called \fIfromName\fR in a class to \fItoName\fR. The +method must have previously existed in the class, and \fItoName\fR must not +previously refer to a method in that class. Does not affect the superclasses +of the class, nor does it affect the subclasses or instances of the class +(except when they have a call chain through the class being modified). Does +not change the export status of the method; if it was exported before, it will +be afterwards. +.SH "CONFIGURING OBJECTS" +.PP +The following commands are supported in the \fIdefScript\fR for +\fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR +form: .TP \fBexport\fI name \fR?\fIname ...\fR? . @@ -294,17 +321,6 @@ This arranges for each of the named methods, \fIname\fR, to be exported being defined. Note that the methods themselves may be actually defined by a class or superclass; object exports override class visibility. .TP -\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR? -. -This slot (see \fBSLOTTED DEFINITIONS\fR below) -sets or updates the list of method names that are used to guard whether a -method call to the object may be called and what the method's results are. -Each \fImethodName\fR names a single filtering method (which may be exposed or -not exposed); it is not an error for a non-existent method to be named. Note -that the actual list of filters also depends on the filters set upon any -classes that the object is an instance of. -By default, this slot works by appending. -.TP \fBforward\fI name cmdName \fR?\fIarg ...\fR? . This creates or updates a forwarded object method called \fIname\fR. The @@ -363,19 +379,6 @@ difference in behavior when used in a private definition context. .RE .VE TIP500 .TP -\fBrenamemethod\fI fromName toName\fR -. -This renames the method called \fIfromName\fR in an object to \fItoName\fR. -The method must have previously existed in the object, and \fItoName\fR must -not previously refer to a method in that object. Does not affect the classes -that the object is an instance of. Does not change the export status of the -method; if it was exported before, it will be afterwards. -.TP -\fBself \fR -.VS TIP470 -This gives the name of the object currently being configured. -.VE TIP470 -.TP \fBunexport\fI name \fR?\fIname ...\fR? . This arranges for each of the named methods, \fIname\fR, to be not exported @@ -408,6 +411,46 @@ instance namespace has a unique prefix that makes accidental use from superclass methods extremely unlikely. .VE TIP500 .RE +.SS "ADVANCED OBJECT CONFIGURATION OPTIONS" +.PP +The following definitions are also supported, but are not required in simple +programs: +.TP +\fBclass\fI className\fR +. +This allows the class of an object to be changed after creation. Note that the +class's constructors are not called when this is done, and so the object may +well be in an inconsistent state unless additional configuration work is done. +.TP +\fBdeletemethod\fI name\fR ?\fIname ...\fR +. +This deletes each of the methods called \fIname\fR from an object. The methods +must have previously existed in that object. Does not affect the classes that +the object is an instance of. +.TP +\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR? +. +This slot (see \fBSLOTTED DEFINITIONS\fR below) +sets or updates the list of method names that are used to guard whether a +method call to the object may be called and what the method's results are. +Each \fImethodName\fR names a single filtering method (which may be exposed or +not exposed); it is not an error for a non-existent method to be named. Note +that the actual list of filters also depends on the filters set upon any +classes that the object is an instance of. +By default, this slot works by appending. +.TP +\fBrenamemethod\fI fromName toName\fR +. +This renames the method called \fIfromName\fR in an object to \fItoName\fR. +The method must have previously existed in the object, and \fItoName\fR must +not previously refer to a method in that object. Does not affect the classes +that the object is an instance of. Does not change the export status of the +method; if it was exported before, it will be afterwards. +.TP +\fBself \fR +.VS TIP470 +This gives the name of the object currently being configured. +.VE TIP470 .SH "PRIVATE METHODS" .VS TIP500 When a class or instance has a private method, that private method can only be @@ -659,6 +702,60 @@ $g update "emailaddress=admins" \fI\(-> DB: update row ::oo::Obj125 with emailaddress=admins\fR .CE .VE TIP478 +.PP +.VS TIP524 +This example shows how to make a custom definition for a class. Note that it +explicitly includes delegation to the existing definition commands via +\fBnamespace path\fR. +.PP +.CS +namespace eval myDefinitions { + # Delegate to existing definitions where not overridden + namespace path \fB::oo::define\fR + + # A custom type of method + proc exprmethod {name arguments body} { + tailcall \fBmethod\fR $name $arguments [list expr $body] + } + + # A custom way of building a constructor + proc parameters args { + uplevel 1 [list \fBvariable\fR {*}$args] + set body [join [lmap a $args { + string map [list VAR $a] { + set [my varname VAR] [expr {double($VAR)}] + } + }] ";"] + tailcall \fBconstructor\fR $args $body + } +} + +# Bind the namespace into a (very simple) metaclass for use +oo::class create exprclass { + \fBsuperclass\fR oo::class + \fBdefinitionnamespace\fR myDefinitions +} + +# Use the custom definitions +exprclass create quadratic { + parameters a b c + exprmethod evaluate {x} { + ($a * $x**2) + ($b * $x) + $c + } +} + +# Showing the resulting class and object in action +quadratic create quad 1 2 3 +for {set x 0} {$x <= 4} {incr x} { + puts [format "quad(%d) = %.2f" $x [quad evaluate $x]] +} + \fI\(-> quad(0) = 3.00\fR + \fI\(-> quad(1) = 6.00\fR + \fI\(-> quad(2) = 11.00\fR + \fI\(-> quad(3) = 18.00\fR + \fI\(-> quad(4) = 27.00\fR +.CE +.VE TIP524 .SH "SEE ALSO" next(n), oo::class(n), oo::object(n) .SH KEYWORDS diff --git a/doc/info.n b/doc/info.n index 5732a13..cf5a438 100644 --- a/doc/info.n +++ b/doc/info.n @@ -481,6 +481,24 @@ list; the first element is the list of arguments to the method in a form suitable for passing to another call to \fBproc\fR or a method definition, and the second element is the body of the method. .TP +\fBinfo class definitionnamespace\fI class\fR ?\fIkind\fR? +.VS TIP524 +This subcommand returns the definition namespace for \fIkind\fR definitions of +the class \fIclass\fR; the definition namespace only affects the instances of +\fIclass\fR, not \fIclass\fR itself. The \fIkind\fR can be either +\fB\-class\fR to return the definition namespace used for \fBoo::define\fR, or +\fB\-instance\fR to return the definition namespace used for +\fBoo::objdefine\fR; the \fB\-class\fR kind is default (though this is only +actually useful on classes that are subclasses of \fBoo::class\fR). +.RS +.PP +If \fIclass\fR does not provide a definition namespace of the specified kind, +this command returns the empty string. In those circumstances, the +\fBoo::define\fR and \fBoo::objdefine\fR commands look up which definition +namespace to use using the class inheritance hierarchy. +.RE +.VE TIP524 +.TP \fBinfo class destructor\fI class\fR . This subcommand returns the body of the destructor of class \fIclass\fR. If no -- cgit v0.12