Index: TODO =================================================================== diff -u -r062dd3cb76774853a767854e29f60a3325c4bd94 -r26480a59b14cf250904da0cdc7d895f21b0ed5fd --- TODO (.../TODO) (revision 062dd3cb76774853a767854e29f60a3325c4bd94) +++ TODO (.../TODO) (revision 26480a59b14cf250904da0cdc7d895f21b0ed5fd) @@ -4007,6 +4007,7 @@ - added documentation for "/obj/ info name" to migration guide and .nxd file - adding more comments to examples in migration guide +- document private properties in tutorial and migration guide ======================================================================== TODO: Index: doc/next-migration.html =================================================================== diff -u -r062dd3cb76774853a767854e29f60a3325c4bd94 -r26480a59b14cf250904da0cdc7d895f21b0ed5fd --- doc/next-migration.html (.../next-migration.html) (revision 062dd3cb76774853a767854e29f60a3325c4bd94) +++ doc/next-migration.html (.../next-migration.html) (revision 26480a59b14cf250904da0cdc7d895f21b0ed5fd) @@ -849,7 +849,7 @@ <li> <p> NX provides means for <em>method protection</em> (method modifiers - <tt>public</tt>, <tt>protected</tt> and <tt>private</tt>). Therefore developers have + <tt>public</tt>, <tt>protected</tt>, and <tt>private</tt>). Therefore developers have to define explicitly public interfaces in order to use methods from other objects. </p> @@ -2693,13 +2693,13 @@ <li> <p> register an accessor function (setter), for wich the usual - protection levels (<tt>public</tt> or <tt>protected</tt>) can be used. + protection levels (<tt>public</tt>, <tt>protected</tt> or <tt>private</tt>) can be used. </p> </li> </ol></div> <div class="paragraph"><p>The method <tt>variable</tt> in NX is similar to <tt>property</tt>, but it creates -only slot objects in cases where needed, and it does not provide -object parameters or accessors.</p></div> +only slot objects in cases where internally needed. <tt>variable</tt> it does +neither provide object parameters, or naccessors.</p></div> <div class="paragraph"><p>We show first the definition of properties simliar to the functionality provided as well by XOTcl and show afterwards how to use value constraints, optional parameters, etc. in NX.</p></div> @@ -2878,8 +2878,6 @@ </tbody> </table> </div> -<div class="paragraph"><p>XOTcl 1 did not support value constraints for object parameters (just -for non-positional arguments).</p></div> <div class="paragraph"><p>NX supports <em>value constraints</em> (value-checkers) for object and method parameters in an orthogonal manner. NX provides a predefined set of value checkers, which can be extended by the application developer. @@ -2934,11 +2932,13 @@ </span><span class='nx-comment'># </span><span class='nx-comment'># User defined value constraints are possible. </span><span class='nx-comment'># All parameter value checkers can be turned on -</span><span class='nx-comment'># and off. +</span><span class='nx-comment'># and off at runtime. </span><span class='nx-comment'># -</span><span class='nx-comment'># Define a boolean property and an integer -</span><span class='nx-comment'># property with a default firstly via "properties", -</span><span class='nx-comment'># then with multiple "property" statements. +</span><span class='nx-comment'># Define a required boolean property "a" +</span><span class='nx-comment'># and an integer property "b" with a default. +</span><span class='nx-comment'># The first definition uses "properties", +</span><span class='nx-comment'># the second definition uses multiple +</span><span class='nx-comment'># "property" statements. </span> <span class='nx-keyword'>Class</span> <span class='nx-keyword'>create</span> Foo -properties { a:boolean @@ -6950,7 +6950,7 @@ <div id="footer"> <div id="footer-text"> Version 2.1<br /> -Last updated 2012-05-21 11:54:16 CEST +Last updated 2012-05-22 09:11:34 CEST </div> </div> </body> Index: doc/next-migration.txt =================================================================== diff -u -r062dd3cb76774853a767854e29f60a3325c4bd94 -r26480a59b14cf250904da0cdc7d895f21b0ed5fd --- doc/next-migration.txt (.../next-migration.txt) (revision 062dd3cb76774853a767854e29f60a3325c4bd94) +++ doc/next-migration.txt (.../next-migration.txt) (revision 26480a59b14cf250904da0cdc7d895f21b0ed5fd) @@ -102,7 +102,7 @@ under arbitrary names for arbitrary objects or classes. .. NX provides means for _method protection_ (method modifiers - +public+, +protected+ and +private+). Therefore developers have + +public+, +protected+, and +private+). Therefore developers have to define explicitly public interfaces in order to use methods from other objects. @@ -1164,11 +1164,11 @@ object (usable via a non-positional parameter during object creation), and . register an accessor function (setter), for wich the usual - protection levels (+public+ or +protected+) can be used. + protection levels (+public+, +protected+ or +private+) can be used. The method +variable+ in NX is similar to +property+, but it creates -only slot objects in cases where needed, and it does not provide -object parameters or accessors. +only slot objects in cases where internally needed. +variable+ it does +neither provide object parameters, or naccessors. We show first the definition of properties simliar to the functionality provided as well by XOTcl and show afterwards how to use @@ -1289,9 +1289,6 @@ ---------------- |====================== -XOTcl 1 did not support value constraints for object parameters (just -for non-positional arguments). - NX supports _value constraints_ (value-checkers) for object and method parameters in an orthogonal manner. NX provides a predefined set of value checkers, which can be extended by the application developer. @@ -1319,11 +1316,13 @@ # # User defined value constraints are possible. # All parameter value checkers can be turned on -# and off. +# and off at runtime. # -# Define a boolean property and an integer -# property with a default firstly via "properties", -# then with multiple "property" statements. +# Define a required boolean property "a" +# and an integer property "b" with a default. +# The first definition uses "properties", +# the second definition uses multiple +# "property" statements. Class create Foo -properties { a:boolean Index: doc/next-tutorial/next-tutorial.html =================================================================== diff -u -ra54313f558be3d0e7c909fa76cdee874f1880ef3 -r26480a59b14cf250904da0cdc7d895f21b0ed5fd --- doc/next-tutorial/next-tutorial.html (.../next-tutorial.html) (revision a54313f558be3d0e7c909fa76cdee874f1880ef3) +++ doc/next-tutorial/next-tutorial.html (.../next-tutorial.html) (revision 26480a59b14cf250904da0cdc7d895f21b0ed5fd) @@ -1623,7 +1623,7 @@ <div class="exampleblock"> <div class="content"> <div class="paragraph"><p>A <strong>property</strong> is a definition of an attribute (an instance variable) -with accessors. The property definition might as well carry +with accessor methods. A property definition might carry value-constraints and a default value.</p></div> </div></div> <div class="imageblock" id="img-person-student" style="text-align:center;"> @@ -2142,15 +2142,15 @@ The call-protection defines from which calling context methods might be called. The Next Scripting Framework supports as well redefinition protection for methods.</p></div> -<div class="paragraph"><p>NX distinguished between <em>public</em>, <em>protected</em> and <em>private</em> methods, -where the default call-protection is "protected".</p></div> +<div class="paragraph"><p>NX distinguishes between <tt>public</tt>, <tt>protected</tt> and <tt>private</tt> methods, +where the default call-protection is <tt>protected</tt>.</p></div> <div class="exampleblock"> <div class="content"> <div class="paragraph"><p>A <strong>public</strong> method can be called from every context. A <strong>protected</strong> method can only be invoked from the same object. A <strong>private</strong> method can only be invoked from methods defined on the same entity (defined on the same class or on the same object) via the invocation -with the local flag (i.e. "<tt>: -local</tt>").</p></div> +with the local flag (i.e. "<tt>: -local foo</tt>").</p></div> </div></div> <div class="paragraph"><p>All kind of method protections are applicable for all kind of methods, either scripted or C-implemented.</p></div> @@ -2275,11 +2275,88 @@ have tried to call the helper of <tt>Sub</tt>, which would be incorrect. For all other purposes, the private methods are "invisible" in all situations, e.g., when mixins are used, or within the <tt>next</tt>-path, etc.</p></div> -<div class="paragraph"><p>By using the <tt>local</tt> flag for the invocation it is possible to call +<div class="paragraph"><p>By using the <tt>-local</tt> flag at the call site it is possible to invoce only the local definition of the method. If we would call the method -as usual, the resolution order would be the same as usual, starting -with filters, mixins, per-object methods and the full intrinsic class -hierarchy.</p></div> +without this flag, the resolution order would be the standard +resolution order, starting with filters, mixins, per-object methods +and the full intrinsic class hierarchy.</p></div> +<div class="paragraph"><p>NX supports the modifier <tt>private</tt> for methods and properties. In all +cases <tt>private</tt> is an instrument to avoid unanticipated interactions +and means actually "accessible for methods defined on the same entity +(object or class)". The main usage for <tt>private</tt> is to improve +locality of the code e.g. for compositional operations.</p></div> +<div class="paragraph"><p>In order to improve locality for properties, a private property +defines therfore internally a variable with a different name to avoid +unintended interactions. The variable should be accessed via the +private accessor, which can be invoved with the <tt>-local</tt> flag. In the +following example class <tt>D</tt> introduces a private property with the +same name as a property in the superclass.</p></div> +<div class="paragraph" id="xmp-private-properties"><div class="title">Listing 27: Private Properties</div><p></p></div> +<div class="listingblock"> +<div class="content"><style type='text/css'> +.nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} +table.nx {border-collapse: collapse; border-spacing: 3px;} +.nx-linenr {border-right: 1px solid #DDDDDD;padding-right: 5px; color: #2B547D;font-style: italic;} +.nx-string {color: #779977; font-weight: normal; font-style: italic;} +.nx-comment {color: #717ab3; font-weight: normal; font-style: italic;} +.nx-keyword {color: #7f0055; font-weight: normal; font-style: normal;} +.nx-placeholder {color: #AF663F; font-weight: normal; font-style: italic;} +.nx-variable {color: #AF663F; font-weight: normal; font-style: normal;} +</style> +<table class='nx'><tr><td class='nx-linenr'><pre> 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 +</pre></td><td class='nx-body'><pre class='nx'><span class='nx-comment'># +</span><span class='nx-comment'># Define a class C with a (public) property "x" +</span><span class='nx-comment'># +</span><span class='nx-keyword'>nx::Class</span> <span class='nx-keyword'>create</span> C { + <span class='nx-keyword'>:property</span> {x c} +} + +<span class='nx-comment'># +</span><span class='nx-comment'># Define a subclass D with a private property "x" +</span><span class='nx-comment'># and a method bar, which is capable of accessing +</span><span class='nx-comment'># the private property. +</span><span class='nx-comment'># +</span><span class='nx-keyword'>nx::Class</span> <span class='nx-keyword'>create</span> D -superclass C { + <span class='nx-keyword'>:private</span> <span class='nx-keyword'>property</span> {x d} + <span class='nx-keyword'>:public</span> <span class='nx-keyword'>method</span> bar {p} {<span class='nx-keyword'>return</span> [: -local <span class='nx-variable'>$p</span>]} +} + +<span class='nx-comment'># +</span><span class='nx-comment'># The private and public (or protected) properties +</span><span class='nx-comment'># define internally separate variable that do not +</span><span class='nx-comment'># conflict. +</span><span class='nx-comment'># +</span>D <span class='nx-keyword'>create</span> d1 +<span class='nx-keyword'>puts</span> [d1 x] ;<span class='nx-comment'># prints "c" +</span><span class='nx-keyword'>puts</span> [d1 bar x] ;<span class='nx-comment'># prints "d"</span></pre></td></tr></table></div></div> +<div class="paragraph"><p>Without the <tt>private</tt> definition of the property, the definition of +property <tt>x</tt> in class <tt>D</tt> would shadow the +definition of the property in the superclass <tt>C</tt> for its instances +(<tt>d1 x</tt> or <tt>set :x</tt> would return <tt>d</tt> instead of <tt>c</tt>).</p></div> </div> <div class="sect2"> <h3 id="_applicability_of_methods">3.4. Applicability of Methods</h3> @@ -2296,7 +2373,7 @@ </div></div> <div class="paragraph"><p>In the following example method, <tt>foo</tt> is an instance method defined on class <tt>C</tt>.</p></div> -<div class="paragraph" id="xmp-instance-applicable"><div class="title">Listing 27: Methods applicable for instances</div><p></p></div> +<div class="paragraph" id="xmp-instance-applicable"><div class="title">Listing 28: Methods applicable for instances</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2341,7 +2418,7 @@ simply by defining the method on an object.</p></div> <div class="paragraph"><p>Note that we can define a per-object method that shadows (redefines) for this object an intrinsic instance method.</p></div> -<div class="paragraph" id="xmp-object-applicable1"><div class="title">Listing 28: Per-object Method</div><p></p></div> +<div class="paragraph" id="xmp-object-applicable1"><div class="title">Listing 29: Per-object Method</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2408,7 +2485,7 @@ <div class="paragraph"><p>The following example defines a public class method <tt>bar</tt> on class <tt>C</tt>. The class method is specified by using the modifier <tt>class</tt> in front of <tt>method</tt> in the method definition command.</p></div> -<div class="paragraph" id="xmp-object-applicable2"><div class="title">Listing 29: Class Methods</div><p></p></div> +<div class="paragraph" id="xmp-object-applicable2"><div class="title">Listing 30: Class Methods</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2493,7 +2570,7 @@ <div class="paragraph"><p>The following example defines an ensemble method for <tt>string</tt>. An ensemble method is defined when the provide method name contains a space.</p></div> -<div class="paragraph" id="xmp-ensemble-methods"><div class="title">Listing 30: Ensemble Method</div><p></p></div> +<div class="paragraph" id="xmp-ensemble-methods"><div class="title">Listing 31: Ensemble Method</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2544,7 +2621,7 @@ of the object. The method can be defined multiple times on the search path, so some of these method definitions might be <em>shadowed</em> by the more specific definitions.</p></div> -<div class="paragraph" id="xmp-method-resolution"><div class="title">Listing 31: Method Resolution with Intrinsic Classes</div><p></p></div> +<div class="paragraph" id="xmp-method-resolution"><div class="title">Listing 32: Method Resolution with Intrinsic Classes</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2610,7 +2687,7 @@ returns empty (and not an error message).</p></div> <div class="paragraph"><p>The introspection method <tt>info precedence</tt> provides information about the order, in which classes processed during method resolution.</p></div> -<div class="paragraph" id="xmp-method-resolution2"><div class="title">Listing 32: Method Resolution with Mixin Classes</div><p></p></div> +<div class="paragraph" id="xmp-method-resolution2"><div class="title">Listing 33: Method Resolution with Mixin Classes</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2676,7 +2753,7 @@ the definitions of the intrinsic class hierarchy. Therefore an invocation of <tt>foo</tt> on object <tt>d1</tt> causes first an invocation of method in the per-object mixin.</p></div> -<div class="paragraph" id="xmp-method-resolution3"><div class="title">Listing 33: Method Invocation Flags</div><p></p></div> +<div class="paragraph" id="xmp-method-resolution3"><div class="title">Listing 34: Method Invocation Flags</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2800,7 +2877,7 @@ determined by its position. When we call a method with non-positional parameters, their meaning is determined via a name passed with the argument during invocation.</p></div> -<div class="paragraph" id="xmp-posnonpos"><div class="title">Listing 34: Positional and Non-Positional Method Parameters</div><p></p></div> +<div class="paragraph" id="xmp-posnonpos"><div class="title">Listing 35: Positional and Non-Positional Method Parameters</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2884,7 +2961,7 @@ </span>o1 baz -x 1 100 o1 baz 200 o1 baz -- -y</pre></td></tr></table></div></div> -<div class="paragraph"><p>Consider the example in <a href="#xmp-posnonpos">Listing 34</a>. The method +<div class="paragraph"><p>Consider the example in <a href="#xmp-posnonpos">Listing 35</a>. The method <tt>foo</tt> has the argument list <tt>x y</tt>. This means that the first argument is passed in an invocation like <tt>o1 foo 1 2</tt> to <tt>x</tt> (here, the value <tt>1</tt>), and the second argument is passed to <tt>y</tt> (here the value <tt>2</tt>). @@ -2893,7 +2970,7 @@ invocation <tt>o1 bar -y 3 -x 1</tt> the names of the parameters are prefixed with a dash ("-"). No matter whether in which order we write the non-positional parameters in the invocation (see line 30 and 31 in -<a href="#xmp-posnonpos">Listing 34</a>) in both cases the variables <tt>x</tt> +<a href="#xmp-posnonpos">Listing 35</a>) in both cases the variables <tt>x</tt> and <tt>y</tt> in the body of the method <tt>bar</tt> get the same values assigned (<tt>x</tt> becomes <tt>1</tt>, <tt>y</tt> becomes <tt>3</tt>).</p></div> <div class="paragraph"><p>It is certainly possible to combine positional and non-positional @@ -2917,7 +2994,7 @@ parameters are optional (they can be left out). By using parameter options, we can as well define positional parameters, which are optional, and non-positional parameters, which are required.</p></div> -<div class="paragraph" id="xmp-optional-req"><div class="title">Listing 35: Optional and Required Method Parameters</div><p></p></div> +<div class="paragraph" id="xmp-optional-req"><div class="title">Listing 36: Optional and Required Method Parameters</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -2971,7 +3048,7 @@ <span class='nx-comment'># invoke foo (one optional positional parameter is missing) </span>o2 foo 1</pre></td></tr></table></div></div> -<div class="paragraph"><p>The example in <a href="#xmp-optional-req">Listing 35</a> defined method <tt>foo</tt> +<div class="paragraph"><p>The example in <a href="#xmp-optional-req">Listing 36</a> defined method <tt>foo</tt> with one required and one optional positional parameter. For this purpose we use the parameter options <tt>required</tt> and <tt>optional</tt>. The parameter options are separated from the parameter name by a colon. If @@ -2980,12 +3057,12 @@ <div class="paragraph"><p>The parameter definition <tt>x:required</tt> for method <tt>foo</tt> is equivalent to <tt>x</tt> without any parameter options (see e.g. previous example), since positional parameters are per default required. The invocation -in line 21 of <a href="#xmp-optional-req">Listing 35</a> will lead to an +in line 21 of <a href="#xmp-optional-req">Listing 36</a> will lead to an undefined variable <tt>y</tt> in method <tt>foo</tt>, because no value us passed to the optional parameter. Note that only trailing positional parameters might be -optional. If we would call method <tt>foo</tt> of <a href="#xmp-posnonpos">Listing 34</a> with only one argument, the system would raise an +optional. If we would call method <tt>foo</tt> of <a href="#xmp-posnonpos">Listing 35</a> with only one argument, the system would raise an exception.</p></div> -<div class="paragraph"><p>Similarly, we define method <tt>bar</tt> in <a href="#xmp-optional-req">Listing 35</a> with one required and one optional non-positional +<div class="paragraph"><p>Similarly, we define method <tt>bar</tt> in <a href="#xmp-optional-req">Listing 36</a> with one required and one optional non-positional parameter. The parameter definition <tt>-y:optional</tt> is equivalent to <tt>-y</tt>, since non-positional parameter are per default optional. However, the non-positional parameter <tt>-x:required</tt> is required. If we @@ -2996,7 +3073,7 @@ <div class="paragraph"><p>Optional parameters might have a default value, which will be used, when not value is provided for this parameter. Default values can be specified for positional and non-positional parameters.</p></div> -<div class="paragraph" id="xmp-default-value"><div class="title">Listing 36: Method Parameters with Default Values</div><p></p></div> +<div class="paragraph" id="xmp-default-value"><div class="title">Listing 37: Method Parameters with Default Values</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3051,7 +3128,7 @@ <div class="paragraph"><p>In order to define a default value, the parameter specification must be of the form of a 2 element list, where the second argument is the default value. See for an example in -<a href="#xmp-default-value">Listing 36</a>.</p></div> +<a href="#xmp-default-value">Listing 37</a>.</p></div> </div> <div class="sect3"> <h4 id="_value_constraints">3.7.4. Value Constraints</h4> @@ -3077,16 +3154,16 @@ <div class="content"> <img src="value-checkers.png" alt="value-checkers.png" /> </div> -<div class="title">Figure 37. General Applicable Value Checkers in NX</div> +<div class="title">Figure 38. General Applicable Value Checkers in NX</div> </div> <div class="paragraph"><p></p></div> -<div class="paragraph"><p><a href="#img-value-checkers">Figure 37</a> shows the built-in +<div class="paragraph"><p><a href="#img-value-checkers">Figure 38</a> shows the built-in general applicable value checkers available in NX, which can be used for all method and object parameters. In the next step, we show how to use these value-checkers for checking permissible values for method parameters. Then we will show, how to provide more detailed value constraints.</p></div> -<div class="paragraph" id="xmp-value-check"><div class="title">Listing 38: Method Parameters with Value Constraints</div><p></p></div> +<div class="paragraph" id="xmp-value-check"><div class="title">Listing 39: Method Parameters with Value Constraints</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3142,10 +3219,10 @@ integer. The parameter specification <tt>o:object,optional</tt> shows how to combine multiple parameter options. The parameter <tt>o</tt> is an optional positional parameter, its value must be an object (see -<a href="#xmp-value-check">Listing 38</a>). Value constraints are +<a href="#xmp-value-check">Listing 39</a>). Value constraints are specified exactly the same way for non-positional parameters (see -method <tt>bar</tt> in <a href="#xmp-value-check">Listing 38</a>).</p></div> -<div class="paragraph" id="xmp-check-parameterized"><div class="title">Listing 39: Parameterized Value Constraints</div><p></p></div> +method <tt>bar</tt> in <a href="#xmp-value-check">Listing 39</a>).</p></div> +<div class="paragraph" id="xmp-check-parameterized"><div class="title">Listing 40: Parameterized Value Constraints</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3218,10 +3295,10 @@ the permissible values to instances of certain classes. We can use for example the native value constraint <tt>object</tt> either for testing whether an argument is some object (without further constraints, as in -<a href="#xmp-default-value">Listing 36</a>, method <tt>foo</tt>), or we can +<a href="#xmp-default-value">Listing 37</a>, method <tt>foo</tt>), or we can constrain the value further to some type (direct or indirect instance of a class). This is shown by method <tt>work</tt> in -<a href="#xmp-check-parameterized">Listing 39</a> which requires +<a href="#xmp-check-parameterized">Listing 40</a> which requires the parameter <tt>-person</tt> to be an instance of class <tt>Person</tt> and the parameter <tt>-project</tt> to be an instance of class <tt>Project</tt>.</p></div> </div> @@ -3234,7 +3311,7 @@ in the next sections. In the following example we define two new value checkers on class <tt>nx::Slot</tt>. The first value checker is called <tt>groupsize</tt>, the second one is called <tt>choice</tt>.</p></div> -<div class="paragraph" id="xmp-user-types"><div class="title">Listing 40: Scripted Value Checker for Method Parameters</div><p></p></div> +<div class="paragraph" id="xmp-user-types"><div class="title">Listing 41: Scripted Value Checker for Method Parameters</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3332,14 +3409,14 @@ (mostly used for the error message) and the second parameter is provided value. The value checker simply tests whether the provided value is between 1 and 3 and raises an exception if this is not the -case (invocation in line 36 in <a href="#xmp-user-types">Listing 40</a>).</p></div> +case (invocation in line 36 in <a href="#xmp-user-types">Listing 41</a>).</p></div> <div class="paragraph"><p>The checker <tt>groupsize</tt> has the permissible values defined in its method’s body. It is as well possible to define more generic checkers that can be parameterized. For this parameterization, one can pass an argument to the checker method (last argument). The checker <tt>choice</tt> can be used for restricting the values to a set of predefined constants. This set is defined in the parameter specification. The -parameter <tt>a</tt> of method <tt>bar</tt> in <a href="#xmp-user-types">Listing 40</a> +parameter <tt>a</tt> of method <tt>bar</tt> in <a href="#xmp-user-types">Listing 41</a> is restricted to the values <tt>red</tt>, <tt>yellow</tt> or <tt>green</tt>, and the parameter <tt>b</tt> is restricted to <tt>good</tt> or <tt>bad</tt>. Note that the syntax of the permissible values is solely defined by the definition of the @@ -3371,7 +3448,7 @@ multiplicity is defined the default multiplicity is <tt>1..1</tt>, which means: provide exactly one (atomic) value (this was the case in the previous examples).</p></div> -<div class="paragraph" id="xmp-multiplicity"><div class="title">Listing 41: Method Parameters with Explicit Multiplicity</div><p></p></div> +<div class="paragraph" id="xmp-multiplicity"><div class="title">Listing 42: Method Parameters with Explicit Multiplicity</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3435,7 +3512,7 @@ <span class='nx-keyword'>puts</span> <span class='nx-string'>"x=$x"</span> } }</pre></td></tr></table></div></div> -<div class="paragraph"><p><a href="#xmp-multiplicity">Listing 41</a> contains three examples for +<div class="paragraph"><p><a href="#xmp-multiplicity">Listing 42</a> contains three examples for positional parameters with different multiplicities. Multiplicity is often combined with value constraints. A parameter specification of the form <tt>x:integer,0..n</tt> means that the parameter <tt>x</tt> receives a list @@ -3446,7 +3523,7 @@ no explicit value is passed for a certain parameter. Another style is to use required or optional parameters. NX does not enforce any particular style for handling unspecified values.</p></div> -<div class="paragraph"><p>All the examples in <a href="#xmp-multiplicity">Listing 41</a> are for +<div class="paragraph"><p>All the examples in <a href="#xmp-multiplicity">Listing 42</a> are for single positional parameters. Certainly, multiplicity is fully orthogonal with the other parameter features and can be used as well for multiple parameters, non-positional parameter, default values, @@ -3512,7 +3589,7 @@ parameters are often used in combination with special setter methods, etc.). Consider the following example, where we define the two application classes <tt>Person</tt> and <tt>Student</tt> with a few properties.</p></div> -<div class="paragraph" id="xmp-object-parameters"><div class="title">Listing 42: Object Parameters</div><p></p></div> +<div class="paragraph" id="xmp-object-parameters"><div class="title">Listing 43: Object Parameters</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3582,13 +3659,13 @@ property <tt>name</tt> is required, the property <tt>birthday</tt> is not. The class <tt>Student</tt> is a subclass of <tt>Person</tt> with the additional required property <tt>matnr</tt> and an optional property <tt>oncampus</tt> with the -default value <tt>true</tt> (see <a href="#xmp-object-parameters">Listing 42</a>). The class diagram below visualizes these +default value <tt>true</tt> (see <a href="#xmp-object-parameters">Listing 43</a>). The class diagram below visualizes these definitions.</p></div> <div class="imageblock" id="img-object-parameters" style="text-align:center;"> <div class="content"> <img src="object-parameter.png" alt="object-parameter.png" /> </div> -<div class="title">Figure 43. System and Application Classes</div> +<div class="title">Figure 44. System and Application Classes</div> </div> <div class="paragraph"><p></p></div> <div class="paragraph"><p>In NX, these definitions imply that instances of the class of <tt>Person</tt> @@ -3598,7 +3675,7 @@ parameters from <tt>Student</tt> (namely <tt>matnr</tt> and <tt>oncampus</tt>). Based on these object parameters, we can create a <tt>Person</tt> named <tt>Bob</tt> and a <tt>Student</tt> named <tt>Susan</tt> with the matriculation number <tt>4711</tt> (see line -23 and 24 in <a href="#xmp-object-parameters">Listing 42</a>). After the object <tt>s1</tt> is created it has the +23 and 24 in <a href="#xmp-object-parameters">Listing 43</a>). After the object <tt>s1</tt> is created it has the instance variables <tt>name</tt>, <tt>matnr</tt> and <tt>oncampus</tt> (the latter is initialized with the default value).</p></div> <div class="sect3"> @@ -3622,7 +3699,7 @@ object parameters. However, this object parameter is positional (last argument) and optional (it can be omitted). The following listing shows (simplified) the object parameters of <tt>Person p1</tt> and <tt>Student s1</tt>.</p></div> -<div class="paragraph" id="xmp-object-parameter-list"><div class="title">Listing 44: Computed Actual Object Parameter (simplified)</div><p></p></div> +<div class="paragraph" id="xmp-object-parameter-list"><div class="title">Listing 45: Computed Actual Object Parameter (simplified)</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3674,7 +3751,7 @@ the same way.</p></div> <div class="paragraph"><p>Since <tt>Student</tt> is an instance of the meta-class <tt>nx::Class</tt> it inherits the object parameters from <tt>nx::Class</tt> (see class diagram -<a href="#img-object-parameters">Figure 43</a>). Therefore, one can +<a href="#img-object-parameters">Figure 44</a>). Therefore, one can use e.g. <tt>-superclass</tt> in the definition of classes.</p></div> <div class="paragraph"><p>Since <tt>nx::Class</tt> is a subclass of <tt>nx::Object</tt>, the meta-class <tt>nx::Class</tt> inherits the parameter definitions from the most general @@ -3684,7 +3761,7 @@ most examples for defining the methods of the class. The following listing shows (simplified) the parameters applicable for <tt>Class Student</tt>.</p></div> -<div class="paragraph" id="xmp-class-parameter-list"><div class="title">Listing 45: Computed Parameters for a Class (simplified)</div><p></p></div> +<div class="paragraph" id="xmp-class-parameter-list"><div class="title">Listing 46: Computed Parameters for a Class (simplified)</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3720,7 +3797,7 @@ <div class="content"> <img src="slots.png" alt="slots.png" /> </div> -<div class="title">Figure 46. Slot Classes and Objects</div> +<div class="title">Figure 47. Slot Classes and Objects</div> </div> <div class="paragraph"><p></p></div> </div> @@ -3790,7 +3867,7 @@ with a method <tt>unknown</tt> which is called in cases, where an unknown method is called. The method unknown receives as first argument the called method followed by the provided arguments</p></div> -<div class="paragraph" id="xmp-unknown-method"><div class="title">Listing 47: Unknown Method Handler</div><p></p></div> +<div class="paragraph" id="xmp-unknown-method"><div class="title">Listing 48: Unknown Method Handler</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3834,7 +3911,7 @@ e.g. lazy loading of these classes. Nsf allows to register multiple unknown handlers, each identified by a key (a unique name, different from the keys of other unknown handlers).</p></div> -<div class="paragraph" id="xmp-unknown-class"><div class="title">Listing 48: Unknown Class Handler</div><p></p></div> +<div class="paragraph" id="xmp-unknown-class"><div class="title">Listing 49: Unknown Class Handler</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3891,7 +3968,7 @@ </span> <span class='nx-comment'># ::M </span>}</pre></td></tr></table></div></div> <div class="paragraph"><p>The Next Scripting Framework allows to add, query, delete and list unknown handlers.</p></div> -<div class="paragraph" id="xmp-unknown-registration"><div class="title">Listing 49: Unknown Handler registration</div><p></p></div> +<div class="paragraph" id="xmp-unknown-registration"><div class="title">Listing 50: Unknown Handler registration</div><p></p></div> <div class="listingblock"> <div class="content"><style type='text/css'> .nx {color: #000000; font-weight: normal; font-style: normal; padding-left: 10px} @@ -3996,7 +4073,7 @@ <div id="footer"> <div id="footer-text"> Version 2.1<br /> -Last updated 2012-05-17 19:25:23 CEST +Last updated 2012-05-22 10:28:25 CEST </div> </div> </body> Index: doc/next-tutorial/next-tutorial.txt =================================================================== diff -u -ra54313f558be3d0e7c909fa76cdee874f1880ef3 -r26480a59b14cf250904da0cdc7d895f21b0ed5fd --- doc/next-tutorial/next-tutorial.txt (.../next-tutorial.txt) (revision a54313f558be3d0e7c909fa76cdee874f1880ef3) +++ doc/next-tutorial/next-tutorial.txt (.../next-tutorial.txt) (revision 26480a59b14cf250904da0cdc7d895f21b0ed5fd) @@ -674,7 +674,7 @@ ========================================= A *property* is a definition of an attribute (an instance variable) -with accessors. The property definition might as well carry +with accessor methods. A property definition might carry value-constraints and a default value. ========================================= @@ -748,6 +748,7 @@ accessor method +name+ to obtain the value of the instance variable +name+ of object +s1+. + ==== Instance Variables without Accessors To define instances variables with default values without accessors @@ -1039,15 +1040,15 @@ be called. The Next Scripting Framework supports as well redefinition protection for methods. -NX distinguished between _public_, _protected_ and _private_ methods, -where the default call-protection is "protected". +NX distinguishes between +public+, +protected+ and +private+ methods, +where the default call-protection is +protected+. =========================================== A *public* method can be called from every context. A *protected* method can only be invoked from the same object. A *private* method can only be invoked from methods defined on the same entity (defined on the same class or on the same object) via the invocation -with the local flag (i.e. "+: -local+"). +with the local flag (i.e. "+: -local foo+"). =========================================== All kind of method protections are applicable for all kind of methods, @@ -1132,12 +1133,62 @@ all other purposes, the private methods are "invisible" in all situations, e.g., when mixins are used, or within the +next+-path, etc. -By using the +local+ flag for the invocation it is possible to call +By using the +-local+ flag at the call site it is possible to invoce only the local definition of the method. If we would call the method -as usual, the resolution order would be the same as usual, starting -with filters, mixins, per-object methods and the full intrinsic class -hierarchy. +without this flag, the resolution order would be the standard +resolution order, starting with filters, mixins, per-object methods +and the full intrinsic class hierarchy. +NX supports the modifier +private+ for methods and properties. In all +cases +private+ is an instrument to avoid unanticipated interactions +and means actually "accessible for methods defined on the same entity +(object or class)". The main usage for +private+ is to improve +locality of the code e.g. for compositional operations. + +In order to improve locality for properties, a private property +defines therfore internally a variable with a different name to avoid +unintended interactions. The variable should be accessed via the +private accessor, which can be invoved with the +-local+ flag. In the +following example class +D+ introduces a private property with the +same name as a property in the superclass. + +[[xmp-private-properties]] +.Listing {counter:figure-number}: Private Properties +{set:xmp-private-properties:Listing {figure-number}} +[source,tcl,numbers] +-------------------------------------------------- +# +# Define a class C with a (public) property "x" +# +nx::Class create C { + :property {x c} +} + +# +# Define a subclass D with a private property "x" +# and a method bar, which is capable of accessing +# the private property. +# +nx::Class create D -superclass C { + :private property {x d} + :public method bar {p} {return [: -local $p]} +} + +# +# The private and public (or protected) properties +# define internally separate variable that do not +# conflict. +# +D create d1 +puts [d1 x] ;# prints "c" +puts [d1 bar x] ;# prints "d" +-------------------------------------------------- + +Without the +private+ definition of the property, the definition of +property +x+ in class +D+ would shadow the +definition of the property in the superclass +C+ for its instances +(+d1 x+ or +set :x+ would return +d+ instead of +c+). + === Applicability of Methods As defined above, a method is a subroutine defined on an object or Index: tests/protected.test =================================================================== diff -u -r62de5715e53f2e8cb8a7f11c62010c33d2723f35 -r26480a59b14cf250904da0cdc7d895f21b0ed5fd --- tests/protected.test (.../protected.test) (revision 62de5715e53f2e8cb8a7f11c62010c33d2723f35) +++ tests/protected.test (.../protected.test) (revision 26480a59b14cf250904da0cdc7d895f21b0ed5fd) @@ -720,15 +720,77 @@ ? {lsort [c1 info vars]} "__private a b" ? {c1 eval {lsort [array names :__private]}} "::C,c ::C,d" - # private property with value constraint + # Private property with value constraint ? {c1 bar d} {1} ? {c1 baz d 2} {2} ? {c1 bar d} {2} ? {c1 baz d x} {expected integer but got "x" for parameter "value"} + + # + # Define a private property with the same name as the private + # property in the superclass; define a public per-object property + # with the same name. The call "d1 c" resolves to the per-object + # property, the private properties are accessed via methods. + # The values of the private properties do not conflict. + # + nx::Class create D -superclass C { + :private property {c c1d} + :public method bard {p} {return [: -local $p]} + :create d1 { + :property {c c1o} + } + } + + ? {d1 bar c} c1 + ? {d1 bard c} c1d + ? {d1 c} c1o + + # + # Define a public property with the same name as the private + # property in the superclass; define private per-object property + # with the same name. The call "d1 c" resolves to the public + # property on D, the private properties are accessed via methods. + # The values of the private properties do not conflict. + # + nx::Class create D -superclass C { + :public property {c c1d} + :public method bard {p} {return [: -local $p]} + :create d1 { + :private property {c c1o} + :public method bard1 {p} {return [: -local $p]} + } + } + + ? {d1 bar c} c1 + ? {d1 bard c} c1d + ? {d1 bard1 c} c1o + ? {d1 c} c1d } +# +# Test properties in class hierarchy, where a subclass defines a +# private property with the same name as a property in a superclass. +# +nx::Test case private-shadows-public-property { + nx::Class create C { + :property {x c} + } + nx::Class create D -superclass C { + :private property {x d} + :public method bar-d {p} {return [: -local $p]} + } + nx::Class create E -superclass D { + :private property {x e} + :public method bar-e {p} {return [: -local $p]} + } + E create e1 + ? {e1 x} c + ? {e1 bar-d x} d + ? {e1 bar-e x} e +} + # # Test protected and private class properties #