Index: ChangeLog-2.0.0-2.1.0.log =================================================================== diff -u -r2a955681817e4db4776d7ae904babe8053c5ad74 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- ChangeLog-2.0.0-2.1.0.log (.../ChangeLog-2.0.0-2.1.0.log) (revision 2a955681817e4db4776d7ae904babe8053c5ad74) +++ ChangeLog-2.0.0-2.1.0.log (.../ChangeLog-2.0.0-2.1.0.log) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -416,11 +416,10 @@ * nsf.c: (ParamOptionParse): 'virtualobjectargs' and 'virtualclassargs' defaulted to ConvertViaCmd when parsed from Tcl spec; explicitly - set ConvertToNothing to match the intended semantics and to avoid + set ConvertToNothing to match the intended semantics and to avoid false warnings (e.g., missing type=virtualobjectargs type checker). [03b838a] - (NsfParameterInfoCmd): Correct two typos in in-code - comment. [6d563e2] + (NsfParameterInfoCmd): Correct two typos in code comment. [6d563e2] 2016-10-02 Stefan Sobernig Index: ChangeLog-2.0b3-2.0b5.log =================================================================== diff -u -r9aa53ef688133d4af8bdff20f8913fe34f8a44ad -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- ChangeLog-2.0b3-2.0b5.log (.../ChangeLog-2.0b3-2.0b5.log) (revision 9aa53ef688133d4af8bdff20f8913fe34f8a44ad) +++ ChangeLog-2.0b3-2.0b5.log (.../ChangeLog-2.0b3-2.0b5.log) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -117,7 +117,7 @@ we might wish a more general solution (see comment for futures releases) - - when creation with an required configure parameter failed, delete the + - when creation with a required configure parameter failed, delete the half-baked object to avoid confusing states. - nx::test: show msg at start of test file Index: ChangeLog-2.0b5-2.0.0.log =================================================================== diff -u -rb5c493afe905b1bafc17697ed3ce01d1662c77b3 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- ChangeLog-2.0b5-2.0.0.log (.../ChangeLog-2.0b5-2.0.0.log) (revision b5c493afe905b1bafc17697ed3ce01d1662c77b3) +++ ChangeLog-2.0b5-2.0.0.log (.../ChangeLog-2.0b5-2.0.0.log) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -529,7 +529,7 @@ function DependentSubClasses(). With the new implementation, NsfParameterCacheClassInvalidateCmd() is as efficient as before without to MostGeneralSuperclass optimization (but being complete now) when - working on the root classes (an more efficient on subclasses). + working on the root classes (and more efficient on subclasses). 2014-06-04 Gustaf Neumann Index: ChangeLog-2.2.0-2.3.0.log =================================================================== diff -u -r63fa317128555211b749beedd51f32e82af6b340 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- ChangeLog-2.2.0-2.3.0.log (.../ChangeLog-2.2.0-2.3.0.log) (revision 63fa317128555211b749beedd51f32e82af6b340) +++ ChangeLog-2.2.0-2.3.0.log (.../ChangeLog-2.2.0-2.3.0.log) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -279,7 +279,7 @@ * nsf.c, speedtest.xotcl: Improved handling of object property autonamed [c86c0775] * serializer.tcl: Preserve overriding slot accessor methods - defined via XOTcl instprocs during serialisation. [542f9ead] + defined via XOTcl instprocs during serialization. [542f9ead] 2019-03-12 Stefan Sobernig @@ -422,7 +422,7 @@ 2018-10-24 Stefan Sobernig * disposition.test, parameters.test: Adjust tests to reflect the - changed representational behaviour for numerics (int, wide) according + changed representational behavior for numerics (int, wide) according to TIP 514 (now in Tcl 8.7a2+). [fca63858] 2018-10-23 Gustaf Neumann Index: doc/Announce2.3.0 =================================================================== diff -u -rfc11b2380eef48346410636908936e9468c74807 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- doc/Announce2.3.0 (.../Announce2.3.0) (revision fc11b2380eef48346410636908936e9468c74807) +++ doc/Announce2.3.0 (.../Announce2.3.0) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -29,7 +29,7 @@ 0 This is to avoid having to rely on pattern sniffing of the - command names. In addition, the propery is now set early enough, + command names. In addition, the property is now set early enough, right after allocating the NSF object, to test for the autonaming condition from within the creation procedure (ttrace). @@ -83,9 +83,9 @@ - XOTcl: - * Improved compatibility of XOTcl2 with XOTcl1 behaviour + * Improved compatibility of XOTcl2 with XOTcl1 behavior for volatile objects (see "volatile reform" above). - * Improved compatibility of XOTcl2 with XOTcl1 behaviour for + * Improved compatibility of XOTcl2 with XOTcl1 behavior for uplevel/upvar from within methods (see "uplevel/ upvar reform" above). Index: doc/next-migration.html =================================================================== diff -u -r6cbeef2d45ae090cf57de7703e0b480125e277b1 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- doc/next-migration.html (.../next-migration.html) (revision 6cbeef2d45ae090cf57de7703e0b480125e277b1) +++ doc/next-migration.html (.../next-migration.html) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -1,6488 +1,6488 @@ - - - - - -Migration Guide for the Next Scripting Language - - - - - + +
+
+
+
+
+
Abstract
+

This document describes the differences between the Next Scripting +Language Framework and XOTcl 1. In particular, it presents a +migration guide from XOTcl 1 to NX, and presents potential +incompatibilities between XOTcl 1 and XOTcl 2.

+
+

The Next Scripting Language (NX) is a successor of XOTcl 1 and is +based on 10 years of experience with XOTcl in projects containing +several hundert thousand lines of code. While XOTcl was the first +language designed to provide language support for design patterns, the +focus of the Next Scripting Framework and NX are on combining this +with Language Oriented Programming. In many respects, NX was designed +to ease the learning of the language by novices (by using a more +mainstream terminology, higher orthogonality of the methods, less +predefined methods), to improve maintainability (remove sources of +common errors) and to encourage developer to write better structured +programs (to provide interfaces) especially for large projects, where +many developers are involved.

+

The Next Scripting Language is based on the Next Scripting Framework +which was developed based on the notion of language oriented +programming. The Next Scripting Frameworks provides C-level support +for defining and hosting multiple object systems in a single Tcl +interpreter. The whole definition of NX is fully scripted +(e.g. defined in nx.tcl). The Next Scripting Framework is shipped +with three language definitions, containing NX and XOTcl 2. Most of +the existing XOTcl 1 programs can be used without modification in the +Next Scripting Framework by using XOTcl 2. The Next Scripting +Framework requires Tcl 8.5 or newer.

+

Although NX is fully scripted (as well as XOTcl 2), our benchmarks +show that scripts based on NX are often 2 or 4 times faster than the +counterparts in XOTcl 1. But speed was not the primary focus on the +Next Scripting Environment: The goal was primarily to find ways to +repackage the power of XOTcl in an easy to learn environment, highly +orthogonal environment, which is better suited for large projects, +trying to reduce maintenance costs.

+

We expect that many user will find it attractive to upgrade +from XOTcl 1 to XOTcl 2, and some other users will upgrade to NX. +This document focuses mainly on the differences between XOTcl 1 and +NX, but addresses as well potential incompatibilities between XOTcl 1 +and XOTcl 2. For an introduction to NX, please consult the NX tutorial.

+
+
+
+

1. Differences Between XOTcl and NX

+
+

The Next Scripting Framework supports Language Oriented Programming +by providing means to define potentially multiple object systems with +different naming and functionality in a single interpreter. This +makes the Next Scripting Framework a powerful instrument for defining +multiple languages such as e.g. domain specific languages. This focus +differs from XOTcl 1.

+

Technically, the language framework approach means that the languages +implemented by the Next Scripting Framework (most prominently XOTcl 2 +and NX) are typically fully scripted and can be loaded via the usual +Tcl package require mechanism.

+

Some of the new features below are provided by the Next Scripting +Framework, some are implemented via the script files for XOTcl 2 and +NX.

+
+

1.1. Features of NX

+

In general, the Next Scripting Language (NX) differs from XOTcl +in the following respects:

+
    +
  1. +

    +Stronger Encapsulation: The Next Scripting Language favors + a stronger form of encapsulation than XOTcl. Calling the own + methods or accessing the own instance variables is typographically + easier and computationally faster than these operations on other + objects. This behavior is achieved via resolvers, which make some + methods necessary in XOTcl 1 obsolete in NX (especially for importing + instance variables). The encapsulation of NX is stronger than in + XOTcl but still weak compared to languages like C++; a developer can + still access other objects' variables via some idioms, but NX makes + accesses to other objects' variables explicit. The requiredness to + make these accesses explicit should encourage developer to implement + well defined interfaces to provide access to instance variables. +

    +
  2. +
  3. +

    +Additional Forms of Method Definition and Reuse: + The Next Scripting Language + provides much more orthogonal means to define, reuse and + introspect scripted and C-implemented methods. +

    +
      +
    1. +

      +It is possible to use NX alias to register methods + under arbitrary names for arbitrary objects or classes. +

      +
    2. +
    3. +

      +NX provides means for method protection (method modifiers + public, protected, and private). Therefore developers have + to define explicitly public interfaces in order to use methods + from other objects. +

      +
    4. +
    5. +

      +One can invoke in NX fully qualified methods to invoke + methods outside the precedence path. +

      +
    6. +
    7. +

      +One can define in NX hierarchical method names (similar to + commands and subcommands, called method ensembles) in a + convenient way to provide extensible, hierarchical naming of + methods. +

      +
    8. +
    9. +

      +One can use in NX the same interface to query (introspect) + C-implemented and scripted methods/commands. +

      +
    10. +
    +
  4. +
  5. +

    +Orthogonal Parameterization: + The Next Scripting Language provides an orthogonal framework for + parametrization of methods and objects. +

    +
      +
    1. +

      +In NX, the same argument parser is used for +

      +
        +
      • +

        +Scripted Methods +

        +
      • +
      • +

        +C-implemented methods and Tcl commands +

        +
      • +
      • +

        +Object Parametrization +

        +
      • +
      +
    2. +
    3. +

      +While XOTcl 1 provided only value-checkers for non-positional + arguments for methods, the Next Scripting Framework provides + the same value checkers for positional and non-positional + arguments of methods, as well as for positional and + non-positional configure parameters (-parameter in + XOTcl 1). +

      +
    4. +
    5. +

      +While XOTcl 1 supported only non-positional arguments at the + begin of the argument list, these can be used now at arbitrary + positions. +

      +
    6. +
    +
  6. +
  7. +

    +Value Checking: +

    +
      +
    1. +

      +The Next Scripting Language supports checking of the input + parameters and the return values of scripted and C-implemented + methods and commands. +

      +
    2. +
    3. +

      +NX provides a set of predefined checkers (like e.g. integer, + boolean, object, …) which can be extended by the + applications. +

      +
    4. +
    5. +

      +Value Checking can be used for single and multi-valued + parameters. One can e.g. define a list of integers + with at least one entry by the parameter specification + integer,1..n. +

      +
    6. +
    7. +

      +Value Checking can be turned on/off globally or on the + method/command level. +

      +
    8. +
    +
  8. +
  9. +

    +Scripted Init Blocks: The Next Scripting Language provides + scripted init blocks for objects and classes (replacement for the + dangerous dash "-" mechanism in XOTcl that allows one to set variables + and invoke methods upon object creation). +

    +
  10. +
  11. +

    +More Conventional Naming for Predefined Methods: The naming of + the methods in the Next Scripting Language is much more in line with + the mainstream naming conventions in OO languages. While for example + XOTcl uses proc and instproc for object specific and inheritable + methods, NX uses simply method. +

    +
  12. +
  13. +

    +Profiling Support: The Next Scripting Language provides now two + forms of profiling +

    +
      +
    • +

      +Profiling via a DTrace provider (examples are e.g. in the dtrace + subdirectory of the source tree) +

      +
    • +
    • +

      +Significantly improved built-in profiling (results can be + processed in Tcl). +

      +
    • +
    +
  14. +
  15. +

    +Significantly Improved Test Suite: The regression test suite of + Next Scripting Scripting framework contain now more than + 5.000 tests, and order of magnitude more than in XOTcl 1.6 +

    +
  16. +
  17. +

    +Much Smaller Interface: The Next Scripting Language has a much + smaller interface (i.e. provides less predefined methods) than + XOTcl (see Table 1), although the expressiveness was increased in + NX. +

    +
  18. +
+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Comparison of the Number of Predefined Methods in NX and XOTcl
NXXOTcl

Total

45

124

Methods for Objects

14

51

Methods for Classes

9

24

Info-methods for Objects

11

25

Info-methods for Classes

11

24

+
+

This comparison list compares mostly XOTcl 1 with NX, some features +are also available in XOTcl 2 (2a, 2c 2d, 3, 4).

+
+
+

1.2. NX and XOTcl Scripts

+

Below is a small, introductory example showing an implementation of a +class Stack in NX and XOTcl. The purpose of this first example is +just a quick overview. We will go into much more detailed comparison +in the next sections.

+

NX supports a block syntax, where the methods are defined during the +creation of the class. The XOTcl syntax is slightly more redundant, +since every definition of a method is a single toplevel command +starting with the class name (also NX supports the style used in +XOTcl). In NX, all methods are per default protected (XOTcl does not +support protection). In NX methods are defined in the definition of +the class via :method or :public method. In XOTcl methods are +defined via the instproc method.

+

Another difference is the notation to refer to instance variables. In +NX, instance variable are named with a single colon in the front. In +XOTcl, instance variables are imported using instvar.

+
+ +++ + + + + + + + + + + + +
Stack example in NX Stack example in XOTcl
+
+
Class create Stack {
+
+   #
+   # Stack of Things
+   #
+
+   :variable things ""
+
+   :public method push {thing} {
+      set :things [linsert ${:things} 0 $thing]
+      return $thing
+   }
+
+   :public method pop {} {
+      set top [lindex ${:things} 0]
+      set :things [lrange ${:things} 1 end]
+      return $top
+   }
+}
+
+
#
+# Stack of Things
+#
+
+Class Stack
+
+Stack instproc init {} {
+   my instvar things
+   set things ""
+}
+
+Stack instproc push {thing} {
+   my instvar things
+   set things [linsert $things 0 $thing]
+   return $thing
+}
+
+Stack instproc pop {} {
+   my instvar things
+   set top [lindex $things 0]
+   set things [lrange $things 1 end]
+}
+
+
+
+

1.3. Using XOTcl 2.0 and the Next Scripting Language in a Single Interpreter

+

In general, the Next Scripting Framework supports multiple object +systems concurrently. Effectively, every object system has different +base classes for creating objects and classes. Therefore, these object +systems can have different interfaces and names of built-in +methods. Currently, the Next Scripting Framework is packaged with +three object systems:

+
    +
  • +

    +NX +

    +
  • +
  • +

    +XOTcl 2.0 +

    +
  • +
  • +

    +TclCool +

    +
  • +
+

XOTcl 2 is highly compatible with XOTcl 1, the language NX is +described below in more details, the language TclCool was introduced +in Tip#279 and serves primarily an example of a small OO language.

+

A single Tcl interpreter can host multiple Next Scripting Object +Systems at the same time. This fact makes migration from XOTcl to NX +easier. The following example script shows to use XOTcl and NX in a +single script:

+
+
Using Multiple Object Systems in a single Script
+
+
namespace eval mypackage {
+
+  package require XOTcl 2.0
+
+  # Define a class with a public method foo using XOTcl
+  xotcl::Class C1
+  C1 instproc foo {} {puts "hello world"}
+
+  package require nx
+
+  # Define a class with a public method foo using NX
+  nx::Class create C2 {
+    :public method foo {} {puts "hello world"}
+  }
+}
+

One could certainly create object or classes from the different object +systems via fully qualified names (e.g. using e.g. ::xotcl::Class or +::nx::Class), but for migration for systems without explicit +namespaces switching between the object systems eases migration. +"Switching" between XOTcl and NX effectively means the load some +packages (if needed) and to import either the base classes (Object and +Class) of XOTcl or NX into the current namespace.

+
+
+
+
+

2. XOTcl Idioms in the Next Scripting Language

+
+

The following sections are intended for reader familiar with XOTcl and +show, how certain language Idioms of XOTcl can be expressed in NX. In +some cases, multiple possible realizations are listed

+
+

2.1. Defining Objects and Classes

+

When creating objects or classes, one should use the method create +explicitly. In XOTcl, a default unknown method handler was provided for +classes, which create for every unknown method invocation an +object/class with the name of the invoked method. This technique was +convenient, but as well dangerous, since typos in method names lead +easily to unexpected behavior. This default unknown method handler is not +provided in NX (but can certainly be provided as a one-liner in NX by +the application).

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
Class ClassName
+
+
Class create ClassName
+
+
Object ObjectName
+
+
Object create ObjectName
+
+
+
+

2.2. Defining Methods

+

In general, both XOTcl and NX support methods on the object level +(per-object methods, i.e. methods only applicable to a single object) +and on the class level (methods inherited to instances of the +classes). While the naming in XOTcl tried to follow closely the Tcl +tradition (using the term proc for functions/methods), NX uses the +term method for defining scripted methods.

+

XOTcl uses the prefix inst to denote that methods are provided for +instances, calling therefore scripted methods for instances +instproc. This is certainly an unusual term. The approach with the +name prefix has the disadvantage, that for every different kind of +method, two names have to be provided (e.g. proc and instproc, +forward and instforward).

+

NX on the contrary uses the same term for defining instance method or +object-specific methods. When the term (e.g. method) is used on a +class, the method will be an instance method (i.e. applicable to the +instances of the class). When the term is used on an object with the +modifier object, an object-specific method is defined. This way one +can define the same way object specific methods on an object as well +as on a class.

+

Furthermore, both XOTcl and NX distinguish between scripted methods +(section 3.2.1) and C-defined methods (section 3.2.2). Section 3.2.3 +introduces method protection, which is only supported by NX.

+
+

2.2.1. Scripted Methods Defined in the Init-block of a Class/Object or with Separate Calls

+

The following examples show the definition of a class and its methods +in the init-block of a class (NX only), and the definition of methods +via separate top level calls (XOTcl and NX).

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Define instance method 'foo' and object
+# method 'bar' for a Class 'C' with separate
+# toplevel commands
+
+Class C
+C instproc foo args {...}
+C proc bar args {...}
+
+
# Define instance method and object method
+# in the init-block of a class
+
+Class create C {
+  :method foo args {...}
+  :object method bar args {...}
+}
+
+
+
# Define instance method and object method
+# with separate commands
+
+Class create C
+C method foo args {...}
+C object method bar args {...}
+
+
# Define object-specific method foo
+# for an object 'o' with separate commands
+
+Object o
+o set x 1
+o proc foo args {...}
+
+
# Define object method and set
+# instance variable in the init-block of
+# an object
+
+Object create o {
+  set :x 1
+  :object method foo args {...}
+}
+
+
+
# Define object method and set
+# instance variable with separate
+# commands
+
+Object create o
+o eval {set :x 1}
+o object method foo args {...}
+
+
+
+

2.2.2. Different Kinds of Methods

+

This section describes various kinds of methods. The different kinds +of methods are defined via different method-defining methods, which +are summarized in the following table for XOTcl and NX.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Methods for defining methods:
+#
+#     proc
+#     instproc
+#     forward
+#     instforward
+#     parametercmd
+#     instparametercmd
+#
+# All these methods return empty.
+
+
# Methods for defining methods:
+#
+#     alias
+#     forward
+#     method
+#
+# All these methods return method-handles.
+
+

In addition to scripted methods (previous section) XOTcl supports +forwarder (called forward and instforward) and accessor functions +to variables (called parametercmd and instparametercmd). The +accessor functions are used normally internally when object-specific +parameters are defined (see Section 3.4).

+

In NX forwarders are called forward. NX does not provide a public +available method to define variable accessors like parametercmd in +XOTcl, but use internally the Next Scripting Framework primitive +nsf::method::setter when appropriate.

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
Class C
+C instforward f1 ...
+C forward f2 ...
+
+Object o
+o forward f3 ...
+
+
# Define forwarder
+
+Class create C {
+  :forward f1 ...
+  :object forward f2 ...
+}
+
+Object create o {
+  :object forward f3 ...
+}
+
+
# Define setter and getter methods in XOTcl.
+#
+# XOTcl provides methods for these.
+
+Class C
+C instparametercmd p1
+C parametercmd p2
+
+Object o
+o parametercmd p3
+
+
# Define setter and getter methods in NX.
+#
+# NX does not provide own methods, but uses
+# the low level framework commands, since
+# application developer will only
+# need it in rare cases.
+
+Class create C
+::nsf::method::setter C p1
+::nsf::method::setter C -per-object p2
+
+Object create o
+::nsf::method::setter o p3
+
+

NX supports in contrary to XOTcl the method alias which can be used +to register arbitrary Tcl commands or methods for an object or class +under a provided method name. Aliases can be used to reuse a certain implementation in +e.g. different object systems under potentially different names. In +some respects aliases are similar to forwarders, but they do not +involve forwarding overhead.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Method "alias" not available
+
+
# Define method aliases
+# (to scripted or non-scripted methods)
+
+Class create C {
+  :alias a1 ...
+  :object alias a2 ...
+}
+
+Object create o {
+  :object alias a3 ...
+}
+
+
+
+

2.2.3. Method Modifiers and Method Protection

+

NX supports four method modifiers object, public, protected and +private. All method modifiers can be written in front of every +method defining command. The method modifier object is used to denote +object-specific methods (see above). The concept of method protection +is new in NX.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Method modifiers
+#
+#   "object",
+#   "public",
+#   "protected", and
+#   "private"
+#
+# are not available
+
+
# Method modifiers
+#
+#   "object",
+#   "public",
+#   "protected"
+#
+# are applicable for all kinds of
+# method defining methods:
+#
+#    method, forward, alias
+#
+# The modifier "private" is available for
+#
+#    method, forward, alias
+#
+Class create C {
+  :/method-definition-method/ ...
+  :public /method-definition-method/ ...
+  :protected /method-definition-method/ ...
+  :private /method-definition-method/ ...
+  :object /method-definition-method/ ...
+  :public object /method-definition-method/ ...
+  :protected object /method-definition-method/ ...
+  :private object /method-definition-method/ ...
+}
+
+

XOTcl does not provide method protection. In NX, all methods are +defined per default as protected. This default can be changed by the +application developer in various ways. The command ::nx::configure +defaultMethodCallProtection true|false can be used to set the default +call protection for scripted methods, forwarder and aliases. +The defaults can be overwritten also on a class level.

+

NX provides means for method hiding via the method modifier +private. Hidden methods can be invoked only via the -local flag, +which means: "call the specified method defined in the same +class/object as the currently executing method".

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# XOTcl provides no means for
+# method hiding
+
+
# Hiding of methods via "private"
+#
+nx::Class create Base {
+  :private method baz {a b} {expr {$a + $b}}
+  :public method foo {a b} {: -local baz $a $b}
+}
+
+nx::Class create Sub -superclass Base {
+  :public method bar {a b} {: -local baz $a $b}
+  :private method baz {a b} {expr {$a * $b}}
+
+  :create s1
+}
+
+s1 foo 3 4  ;# returns 7
+s1 bar 3 4  ;# returns 12
+s1 baz 3 4  ;# unable to dispatch method 'baz'
+
+
+
+

2.2.4. Method Deletion

+

NX provides an explicit delete method for the deletion of methods.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# XOTcl provides only method deletion with
+# the equivalent of Tcl's "proc foo {} {}"
+/cls/ instproc foo {} {}
+/obj/ proc foo {} {}
+
+
# Deletion of Methods
+#
+/cls/ delete method /name/
+/obj/ delete object method /name/
+
+
+
+
+

2.3. Resolvers

+

The Next Scripting Framework defines Tcl resolvers for method and +variable names to implement object specific behavior. Within the +bodies of scripted methods these resolver treat variable and function +names starting with a colon : specially. In short, a colon-prefixed +variable name refers to an instance variable, and a colon-prefixed +function name refers to a method. The sub-sections below provide +detailed examples.

+

Note that the resolvers of the Next Scripting Framework can be used in +the XOTcl 2.* environment as well.

+
+

2.3.1. Invoking Methods

+

In XOTcl, a method of the same object can be invoked via my, or in +general via using the name of the object in front of the method name.

+

In NX, the own methods are called via the method name prefixed with a +single colon. The invocation of the methods of other objects is the +same in NX and XOTcl.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
Class C
+C instproc foo args {...}
+C instproc bar args {
+  my foo 1 2 3 ;# invoke own method
+  o baz        ;# invoke other object's method
+}
+Object o
+o proc baz {} {...}
+
+
Class create C {
+  :method foo args {...}
+  :method bar args {
+     :foo 1 2 3 ;# invoke own method
+     o baz      ;# invoke other object's method
+  }
+}
+Object create o {
+  :public object method baz {} {...}
+}
+
+
+
+

2.3.2. Accessing Own Instance Variables from Method Bodies

+

In general, the Next Scripting Language favors the access to an +objects’s own instance variables over variable accesses of other +objects. This means that in NX it is syntactically easier to access +the own instance variables. On the contrary, in XOTcl, the variable +access to own and other variables are fully symmetric.

+

In XOTcl, the following approaches are used to access instance +variables:

+
    +
  • +

    +Import instance variables via instvar and access variables via $varName +

    +
  • +
  • +

    +Set or get instance variables via my set varName ?value? or other + variable accessing methods registered on xotcl::Object such as + append, lappend, incr, etc. +

    +
  • +
  • +

    +Register same-named accessor functions and set/get values + of instance variables via my varName ?value? +

    +
  • +
+

In NX, the favored approach to access instance variables is to use +the name resolvers, although it is as well possible to import +variables via nx::var import or to check for the existence of +instance variables via nx::var exists.

+

The following examples summary the use cases for accessing the own and +other instance variables.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
Class C
+C instproc foo args {
+  # Method scoped variable a
+  set a 1
+  # Instance variable b
+  my instvar b
+  set b 2
+  # Global variable/namespaced variable c
+  set ::c 3
+}
+
+
Class create C {
+  :method foo args {...}
+    # Method scoped variable a
+    set a 1
+    # Instance variable b
+    set :b 2
+    # Global variable/namespaced variable c
+    set ::c 3
+  }
+}
+
+
... instproc ... {
+   my set /varName/ ?value?
+}
+
+
# Set own instance variable to a value via
+# resolver (preferred and fastest way)
+
+... method ... {
+   set :/newVar/ ?value?
+}
+
+
... instproc ... {
+   my instvar /varName/
+   set /varName/ ?value?
+}
+
+
# Set own instance variable via
+# variable import
+
+... method ... {
+   ::nx::var import [self] /varName/
+   set /varName/ ?value?
+}
+
+
... instproc ... {
+   set /varName/ [my set /otherVar/]
+}
+
+
# Read own instance variable
+
+... method ... {
+   set /varName/ [set :/otherVar/]
+}
+
+
+
... method ... {
+   set /newVar/ ${:/otherVar/}
+}
+
+
... instproc ... {
+   my exists /varName/
+}
+
+
# Test existence of own instance variable
+
+... method ... {
+   info :/varName/
+}
+
+
+
 ... method ... {
+   ::nx::var exists [self] /varName/
+}
+
+
+
+

2.3.3. Accessing Instance Variables of other Objects

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ set /varName/ ?value?
+
+
# Set instance variable of object obj to a
+# value via resolver
+# (preferred way: define property on obj)
+
+/obj/ eval [list set :/varName/ ?value?]
+
+
set /varName/ [/obj/ set /otherVar/]
+
+
# Read instance variable of object obj
+# via resolver
+
+set /varName/ [/obj/ eval {set :/otherVar/}]
+
+
... instproc ... {
+   /obj/ instvar /varName/
+   set /varName/ ?value?
+}
+
+
# Read instance variable of object /obj/
+# via import
+
+... method ... {
+   ::nx::var import /obj/ /varName/
+   set /varName/ ?value?
+}
+
+
/obj/ exists varName
+
+
# Test existence of instance variable of
+# object obj
+
+/obj/ eval {info exists :/varName/}
+
+
+
::nx::var exists /obj/ /varName/
+
+
+
+
+

2.4. Parameters

+

While XOTcl 1 had very limited forms of parameters, XOTcl 2 and NX +provide a generalized and highly orthogonal parameter machinery +handling various kinds of value constraints (also called value +checkers). Parameters are used to specify,

+
    +
  • +

    +how objects and classes are initialized (we call these parameter types + Configure Parameters), and +

    +
  • +
  • +

    +what values can be passed to methods (we call these Method + Parameters). +

    +
  • +
+

Furthermore, parameters might be positional or non-positional, they +might be optional or required, they might have a defined multiplicity, +and value-types, they might be introspected, etc. The Next Scripting +Framework provide a unified, C-implemented infrastructure to handle +both, object and method parameters in the same way with a high degree +of orthogonality.

+

Configuration parameters were specified in XOTcl 1 primarily via the +method parameter in a rather limited way, XOTcl 1 only supported +non-positional parameters in front of positional ones, supported no +value constraints for positional parameters, provided no distinction +between optional and required, and did not support multiplicity.

+

Furthermore, the Next Scripting Framework provides optionally Return +Value Checking based on the same mechanism to check whether some +methods return always the values as specified.

+
+

2.4.1. Parameters for Configuring Objects: Variables and Properties

+

Configure parameters are used for specifying values for configuring +objects when they are created (i.e. how instance variables are +initialized, what parameters can be passed in for initialization, what +default values are used, etc.). Such configuration parameters are +supported in XOTcl primarily via the method parameter, which is used +in XOTcl to define multiple parameters via a list of parameter +specifications.

+

Since the term "parameter" is underspecified, NX uses a more +differentiated terminology. NX distinguishes between configurable +instance variables (also called properties) and non configurable +instance variables (called variables), which might have as well +e.g. default values. The values of configurable properties can be +queried at runtime via cget, and their values can be altered via +configure. When the value of a configure parameter is provided or +changed, the value checkers from the variable definition are used to +ensure, the value is permissible (i.e. it is for example an integer +value). The sum of all configurable object parameters are called +configure parameters. To define a define a configurable variable, NX +uses the method property, for non-configurable variables, the method +variable is used.

+

Optionally, one can define in NX, that a property or a +variable should have a public, protected or private accessor. Such +an accessor is a method with the same name as the variable. In XOTcl, +every parameter defined as well automatically a same-named accessor +method, leading to potential name conflicts with other method names.

+

In the examples below we show the definition of configurable a non-configurable instance variables using variable and property +respectively.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Define class "Foo" with instance
+# variables "x" and "y" initialized
+# on instance creation. The initialization
+# has to be performed in the constructor.
+
+Class Foo
+Foo instproc init args {
+   instvar x y
+   set x 1
+   set y 2
+}
+
+# Create instance of the class Foo
+Foo f1
+
+# Object f1 has instance variables
+# x == 1 and y == 2
+
+
# Define class "Foo" with instance variables
+# "x" and "y" initialized on instance creation.
+# The method "variable" is similar in syntax
+# to Tcl's "variable" command. During
+# instance creation, the variable
+# definitions are used for the
+# initialization of the variables of the object.
+
+Class create Foo {
+  :variable x 1
+  :variable y 2
+}
+
+# Create instance of the class Foo
+Foo create f1
+
+# Object f1 has instance variables
+# x == 1 and y == 2
+
+

While XOTcl follows a procedural way to initialize variables via the +constructor init, NX follows a more declarative approach. Often, +classes have superclasses, which often want to provide their own +instance variables and default values. The declarative approach from +NX solves this via inheritance, while a procedural approach via +assign statements in the constructor requires explicit constructor +calls, which are often error-prone. Certainly, when a user prefers to +assign initial values to instance variables via explicit assign +operations in constructors, this is as well possible in NX.

+

NX uses the same mechanism to define class variables or object +variables.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# No syntactic support for creating
+# class variables
+
+
+# Define a object variable "V" with value 100 and
+# an instance variable "x". "V" is defined for the
+# class object Foo, "x" is defined in the
+# instances of the class. "object variable" works
+# similar to "object method".
+
+Class create Foo {
+  :object variable V 100
+  :variable x 1
+}
+
+

In the next step, we define configurable instance variables which we +call properties in NX.

+

XOTcl uses the method parameter is a shortcut for creating multiple +configurable variables with automatically created accessors (methods for +reading and writing of the variables). In NX, the preferred way to +create configurable variables is to use the method property. The +method property in NX is similar to variable, but makes the +variables configurable, which means that

+
    +
  1. +

    +one can specify the property as a non-positional parameter upon + creation of the object, +

    +
  2. +
  3. +

    +one can query the value via the method cget, and +

    +
  4. +
  5. +

    +one can modify the value of the underlying variable via the method + configure. +

    +
  6. +
+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Parameters specified as a list
+# (short form); parameter
+# "a" has no default, "b" has default "1"
+
+Class Foo -parameter {a {b 1} {c "[info tclversion]"}}
+
+# Create instance of the class Foo
+Foo f1 -a 0
+
+# Object f1 has instance variables
+# a == 0 and b == 1
+
+# XOTcl registers automatically accessors
+# for the parameters. Use the accessor
+# "b" to output the value of variable "b"
+puts [f1 b]
+
+# Use the setter to alter value of
+# instance variable "b"
+f1 b 100
+
+# Return the substituted value of
+# parameter "c", something like 8.7.
+# XOTcl substitutes always when it sees
+# square brackets or dollar signs.
+f1 c
+
+
+
# Define property "a" and "b". The
+# property "a" has no default, "b" has
+# default value "1"
+
+Class create Foo {
+  :property a
+  :property {b 1}
+  :property {c "[info tclversion]"}
+  :property {d:substdefault "[info tclversion]"}
+}
+
+# Create instance of the class Foo
+Foo create f1 -a 0
+
+# Object f1 has instance variables
+# a == 0 and b == 1
+
+# Use the method "cget" to query the value
+# of a configuration parameter
+puts [f1 cget -b]
+
+# Use the method "configure" to alter the
+# value of instance variable "b"
+f1 configure -b 100
+
+# Return the (non substituted) value of
+# parameter "c", and the substituted value
+# of parameter "d"
+f1 cget -c
+f1 cget -d
+
+
+

In general, NX allows one to create variables and properties with and +without accessor methods. The created accessor methods might be +public, protected or public. When the value none is provided +to -accessor, no accessor will be created. This is actually the +default in NX. In order to change the default behavior in NX, one can use +::nx::configure defaultAccessor none|public|protected|private.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# "parameter" creates always accessor
+# methods, accessor methods are
+# always public, no "cget" is available.
+
+Class create Foo -parameter {a {b 1}}
+
+# Use the accessor method to query
+# the value of a configuration parameter
+puts [f1 b]
+
+# Use the accessor method to set the
+# value of instance variable "a"
+f1 a 100
+
+# Use the accessor method to unset the
+# value of instance variable "a" n.a. via
+# accessor
+
+
# Define property "a" and "b". The
+# property "a" has no default, "b" has
+# default value "1"
+
+Class create Foo {
+  :variable -accessor public a
+  :property -accessor public {b 1}
+}
+
+# Use the accessor method to query
+# the value of a configuration parameter
+puts [f1 b get]
+
+# Use the accessor method to set the
+# value of instance variable "a"
+f1 a set 100
+
+# Use the accessor method to unset the
+# value of instance variable "a"
+f1 a unset
+
+

Similar to variable, properties can be defined in NX on the class +and on the object level.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# XOTcl provides no means to define
+# configurable variables at the object
+# level
+
+
# Define class with a property for the class object
+# named "cp". This is similar to "static variables"
+# in some other object-oriented programming
+# languages.
+
+Class create Foo {
+  ...
+  :object property cp 101
+}
+
+# Define object property "op"
+
+Object create o {
+  :object property op 102
+}
+
+

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. +In NX, the value checking is optional. This means that it is possible to +develop e.g. which a large amount of value-checking and deploy the +script with value checking turned off, if the script is highly +performance sensitive.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# No value constraints for
+# parameter available
+
+
# Predefined value constraints:
+#    object, class, alnum, alpha, ascii, boolean,
+#    control, digit, double, false, graph, integer,
+#    lower, parameter, print, punct, space, true,
+#    upper, wordchar, xdigit
+#
+# User defined value constraints are possible.
+# All parameter value checkers can be turned on
+# and off at runtime.
+#
+# 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
+   {b:integer 1}
+}
+
+
+
Class create Foo {
+   :property a:boolean
+   :property {b:integer 1}
+}
+
+

In XOTcl all configure parameters were optional. Required parameters have +to be passed to the constructor of the object.

+

NX allows one to define optional and required configure parameters (as +well as method parameters). Therefore, configure parameters can be used +as the single mechanism to parametrize objects. It is in NX not +necessary (and per default not possible) to pass arguments to the +constructor.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Required parameter not available
+
+
# Required parameter:
+# Define a required property "a" and a
+# required boolean property "b"
+
+Class create Foo -properties {
+   a:required
+   b:boolean,required
+}
+
+
+
+Class create Foo {
+   :property a:required
+   :property b:boolean,required
+}
+
+

NX supports in contrary to XOTcl to define the multiplicity of values +per parameter. In NX, one can specify that a parameter can accept the +value "" (empty) in addition to e.g. an integer, or one can specify that the +value is an empty or non-empty list of values via the multiplicity. For +every specified value, the value checkers are applied.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Multiplicity for parameter
+# not available
+
+
# Parameter with multiplicity
+#   ints is a list of integers, with default
+#   objs is a non-empty list of objects
+#   obj is a single object, maybe empty
+
+Class create Foo -properties {
+  {ints:integer,0..n ""}
+   objs:object,1..n
+   obj:object,0..1
+}
+
+
+
Class create Foo {
+  :property {ints:integer,0..n ""}
+  :property objs:object,1..n
+  :property obj:object,0..1
+}
+
+

For the implementation of variables and properties, NX uses slot +objects, which are an extension to the -slots already available in +XOTcl. While very for every property in NX, a slot object is created, +for performance reasons, not every variable has a slot associated.

+

When a property is created, NX does actually three things:

+
    +
  1. +

    +Create a slot object, which can be specified in more detail + using the init-block of the slot object +

    +
  2. +
  3. +

    +Create a parameter definition for the initialization of the + object (usable via a non-positional parameter during object + creation), and +

    +
  4. +
  5. +

    +register optionally an accessor function (setter), for which the usual + protection levels (public, protected or private) can be used. +

    +
  6. +
+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Define parameters via slots
+
+Class Foo -slots {
+   Attribute a
+   Attribute b -default 1
+}
+
+# Create instance of the class Foo
+# and provide a value for instance
+# variable "a"
+Foo f1 -a 0
+
+# Object f1 has a == 0 and b == 1
+
+
# Configurable parameters specified via the
+# method "property" (supports method
+# modifiers and scripted configuration;
+# see below)
+
+Class create Foo {
+   :property a
+   :property {b 1}
+}
+
+# Create instance of the class Foo and
+# provide a value for instance variable "a"
+Foo create f1 -a 0
+
+# Object f1 has a == 0 and b == 1
+
+

Since the slots are objects, the slot objects can be configured and +parametrized like every other object in NX. Slot objects can be +provided with a scripted initialization as well. We show first the +definition of properties similar to the functionality provided as well +by XOTcl and show afterwards how to use value constraints, optional +parameters, etc. in NX.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Define parameter with an
+# attribute-specific type checker
+
+Class Person -slots {
+  Attribute create sex -type "sex" {
+    my proc type=sex {name value} {
+      switch -glob $value {
+        m* {return m}
+        f* {return f}
+        default {
+          error "expected sex but got $value"
+        }
+      }
+    }
+  }
+}
+
+
# Configure parameter with scripted
+# definition (init-block), defining a
+# property specific type checker
+
+Class create Person {
+    :property -accessor public sex:sex,convert {
+
+      # define a converter to standardize representation
+      :object method type=sex {name value} {
+        switch -glob $value {
+          m* {return m}
+          f* {return f}
+          default {error "expected sex but got $value"}
+        }
+      }
+
+    }
+}
+
+

The parameters provided by a class for the initialization of +instances can be introspected via querying the parameters +of the method create: /cls/ info lookup parameters create +(see [info_configure_parameter]).

+
+
+

2.4.2. Delete Variable Handlers

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# No syntactic support for deleting
+# variable handlers
+
+
# Like deletion of Methods:
+# Delete on the object, where the
+# variable handler is defined.
+
+/cls/ delete property /name/
+/obj/ delete object property /name/
+
+/cls/ delete variable /name/
+/obj/ delete object variable /name/
+
+
+
+

2.4.3. Method Parameters

+

Method parameters are used to specify the interface of a single method +(what kind of values may be passed to a method, what default values +are provided etc.). The method parameters specifications in XOTcl 1 +were limited and allowed only value constraints for non positional +arguments.

+

NX and XOTcl 2 provide value constraints for all kind of method parameters. +While XOTcl 1 required non-positional arguments to be listed in front of +positional arguments, this limitation is lifted in XOTcl 2.

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Define method foo with non-positional
+# parameters (x, y and y) and positional
+# parameter (a and b)
+
+Class C
+C instproc foo {
+   -x:integer
+   -y:required
+   -z
+   a
+   b
+} {
+   # ...
+}
+C create c1
+
+# invoke method foo
+c1 foo -x 1 -y a 2 3
+
+
# Define method foo with
+# non-positional parameters
+# (x, y and y) and positional
+# parameter (a and b)
+
+Class create C {
+   :public method foo {
+      -x:integer
+      -y:required
+      -z
+      a
+      b
+   } {
+      # ...
+   }
+   :create c1
+}
+# invoke method foo
+c1 foo -x 1 -y a 2 3
+
+
# Only leading non-positional
+# parameters are available; no
+# optional positional parameters,
+# no value constraints on
+# positional parameters,
+# no multiplicity, ...
+
+
# Define various forms of parameters
+# not available in XOTcl 1
+
+Class create C {
+  # trailing (or interleaved) non-positional
+  # parameters
+  :public method m1 {a b -x:integer -y} {
+    # ...
+  }
+
+  # positional parameters with value constraints
+  :public method m2 {a:integer b:boolean} {
+    #...
+  }
+
+  # optional positional parameter (trailing)
+  :public method set {varName value:optional} {
+    # ....
+  }
+
+  # parameter with multiplicity
+  :public method m3 {-objs:object,1..n c:class,0..1} {
+    # ...
+  }
+
+  # In general, the same list of value
+  # constraints as for configure parameter is
+  # available (see above).
+  #
+  # User defined value constraints are
+  # possible. All parameter value checkers
+  # can be turned on and off.
+}
+
+
+
+

2.4.4. Return Value Checking

+

Return value checking is a functionality available in the Next +Scripting Framework, that was not yet available in XOTcl 1. A return +value checker assures that a method returns always a value satisfying +some value constraints. Return value checkers can be defined on all +forms of methods (scripted or C-implemented). Like for other value +checkers, return value checkers can be turned on and off.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# No return value checking
+# available
+
+
# Define method foo with non-positional
+# parameters (x, y and y) and positional
+# parameter (a and b)
+
+Class create C {
+
+  # Define method foo which returns an
+  # integer value
+  :method foo -returns integer {-x:integer} {
+    # ...
+   }
+
+  # Define an alias for the Tcl command ::incr
+  # and assure, it always returns an integer
+  # value
+  :alias incr -returns integer ::incr
+
+  # Define a forwarder that has to return an
+  # integer value
+  :forward ++ -returns integer ::expr 1 +
+
+ # Define a method that has to return a
+ # non-empty list of objects
+ :public object method instances {} \
+    -returns object,1..n {
+   return [:info instances]
+  }
+}
+
+
+
+
+

2.5. Interceptors

+

XOTcl and NX allow the definition of the same set of interceptors, +namely class- and object-level mixins and class- and object-level +filters. The primary difference in NX is the naming, since NX abandons +the prefix "inst" from the names of instance specific method, but uses +the modifier object" for object specific methods.

+

Therefore, in NX, if a mixin is registered on a class-level, it is +applicable for the instances (a per-class mixin), and if and object +mixin is registered, it is a per-object mixin. In both cases, the +term mixin is used, in the second case with the modifier +object. As in all other cases, one can register the same way a +per-object mixin on a plain object or on a class object.

+
+

2.5.1. Register Mixin Classes and Mixin Guards

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/cls/ instmixin ...
+/cls/ instmixinguard /mixin/ ?condition?
+
+# Query per-class mixin
+/cls/ instmixin
+
+
# Register/clear per-class mixin and guard for
+# a class
+
+/cls/ mixins add|set|clear ...
+/cls/ mixins guard /mixin/ ?condition?
+/cls/ configure -mixin ...
+
+# Query per-class mixins
+/cls/ mixins get
+/cls/ cget -mixins
+
+# Query per-class mixins (without guards)
+/cls/ mixins classes
+
+
/obj/ mixin ...
+/obj/ mixinguard /mixin/ ?condition?
+
+# Query per-object mixins
+/obj/ mixin
+
+
# Register/clear per-object mixin and guard for
+# an object
+
+/obj/ object mixins add|set|clear ...
+/obj/ object mixins guard /mixin/ ?condition?
+/obj/ configure -object-mixins ...
+
+# Query per-object mixin
+/obj/ object mixins get
+/obj/ cget -object-mixin
+
+# Query per-object mixins (without guards)
+/cls/ mixins classes
+
+
+
+

2.5.2. Register Filters and Filter Guards

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# Register per-class filter and guard for
+# a class
+/cls/ instfilter ...
+/cls/ instfilterguard /filter/ ?condition?
+
+# Query per-class filter
+/cls/ instfilter
+
+
# Register/clear per-class filter and guard for
+# a class
+
+/cls/ filters add|set|clear ...
+/cls/ filters guard /filter/ ?condition?
+/cls/ configure -filters ...
+
+# Query per-class filters
+/cls/ filters get
+/cls/ cget -filters
+
+# Query per-class filters (without guards)
+/cls/ filters methods
+
+
/obj/ filter ...
+/obj/ filterguard /filter/ ?condition?
+
+
# Register(clear per-object filter and guard for
+# an object
+
+/obj/ object filters add|set|clear ...
+/obj/ object filters guard /filter/ ?condition?
+/obj/ configure -object-filters ...
+
+# Query per-object filters
+/cls/ object filters get
+/obj/ cget -object-filters
+
+# Query per-object filters (without guards)
+/cls/ object filters methods
+
+
+
+
+

2.6. Introspection

+

In general, introspection in NX became more orthogonal and less +dependent on the type of the method. In XOTcl it was e.g. necessary +that a developer had to know, whether a method is e.g. scripted or not +and has to use accordingly different sub-methods of info.

+

In NX, one can use e.g. always info method with a subcommand and the +framework tries to hide the differences as far as possible. So, one +can for example obtain with info method parameter the parameters of +scripted and C-implemented methods the same way, one can get the +definition of all methods via info method definition and one can get +an manual-like interface description via info method +syntax. In addition, NX provides means to query the type of +a method, and NX allows one to filter by the type of the method.

+
+

2.6.1. List sub- and superclass relations

+

While XOTcl used singular words for introspecting sub- and superclass +relations, NX uses plural word to indicate that potentially a list of +values is returned.

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/cls/ info superclass ?pattern?
+
+
/cls/ info superclasses ?pattern?
+
+
/cls/ info subclass ?pattern?
+
+
/cls/ info subclasses -type setter ?pattern?
+
+
+
+

2.6.2. List methods defined by classes

+

While XOTcl uses different names for obtaining different kinds of +methods defined by a class, NX uses info methods in an orthogonal +manner. NX allows as well to use the call protection to filter the +returned methods.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/cls/ info instcommands ?pattern?
+
+
/cls/ info methods ?pattern?
+
+
/cls/ info instparametercmd ?pattern?
+
+
/cls/ info methods -type setter ?pattern?
+
+
/cls/ info instprocs ?pattern?
+
+
/cls/ info methods -type scripted ?pattern?
+
+
# n.a.
+
+
/cls/ info methods -type alias ?pattern?
+/cls/ info methods -type forwarder ?pattern?
+/cls/ info methods -type object ?pattern?
+/cls/ info methods -callprotection public|protected ...
+
+
+
+

2.6.3. List methods defined by objects

+

While XOTcl uses different names for obtaining different kinds of +methods defined by an object, NX uses info methods in an orthogonal +manner. NX allows as well to use the call protection to filter the +returned methods.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ info commands ?pattern?
+
+
/obj/ info object methods ?pattern?
+
+
/obj/ info parametercmd ?pattern?
+
+
/obj/ info object methods -type setter ?pattern?
+
+
/obj/ info procs ?pattern?
+
+
/obj/ info object methods -type scripted ?pattern?
+
+
# n.a.
+
+
/obj/ info object methods -type alias ?pattern?
+/obj/ info object methods -type forwarder ?pattern?
+/obj/ info object methods -type object ?pattern?
+/obj/ info object methods -callprotection public|protected ...
+
+
+
+

2.6.4. Check existence of a method

+

NX provides multiple ways of checking, whether a method exists; one +can use info method exists to check, if a given method exists +(return boolean), or one can use info methods ?pattern?, where +pattern might be a single method name without wild-card +characters. The method info methods ?pattern? returns a list of +matching names, which might be empty. These different methods appear +appropriate depending on the context.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj|cls/ info \
+   [inst](commands|procs|parametercmd) \
+   ?pattern?
+
+
/cls/ info method exists /methodName/
+/cls/ info methods /methodName/
+/obj/ info object method exists /methodName/
+/obj/ info object methods /methodName/
+
+
+
+

2.6.5. List callable methods

+

In order to obtain for an object the set of artefacts defined in the + class hierarchy, NX uses info lookup. One can either lookup methods + (via info lookup methods) or slots (via info lookup slots). The + plural term refers to a potential set of return values.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ info methods ?pattern?
+
+
/obj/ info lookup methods ... ?pattern?
+# Returns list of method names
+
+
# n.a.
+
+
# List only application specific methods
+/obj/ info lookup methods -source application ... ?pattern?
+# Returns list of method names
+
+
# Options for 'info methods'
+#
+# -incontext
+# -nomixins
+
+
# Options for 'info lookup methods'
+#
+# -source ...
+# -callprotection ...
+# -incontext
+# -type ...
+# -nomixins
+
+
# n.a.
+
+
# List slot objects defined for obj
+# -source might be all|application|baseclasses
+# -type is the class of the slot object
+
+/obj/ info lookup slots ?-type ...? ?-source ...? ?pattern?
+
+# Returns list of slot objects
+
+
# List registered filters
+/obj/ info filters -order ?-guards? ?pattern?
+
+# List registered mixins
+/obj/ info mixins -heritage ?-guards? ?pattern?
+
+
# List registered filters
+/obj/ info lookup filters ?-guards? ?pattern?
+
+# List registered mixins
+/obj/ info lookup mixins ?-guards? ?pattern?
+
+
+
+

2.6.6. List object/class where a specified method is defined

+

info lookup can be used as well to determine, where exactly an + artefact is located. One can obtain this way a method handle, where +a method or filter is defined.

+

The concept of a method-handle is new in NX. The method-handle +can be used to obtain more information about the method, such as +e.g. the definition of the method.

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ procsearch /methodName/
+
+
/obj/ info lookup method /methodName/
+# Returns method-handle
+
+
/obj/ filtersearch /methodName/
+
+
/obj/ info lookup filter /methodName/
+# Returns method-handle
+
+
+
+

2.6.7. List definition of scripted methods

+

XOTcl contains a long list of info subcommands for different kinds of +methods and for obtaining more detailed information about these +methods.

+

In NX, this list of info subcommands is much shorter and more +orthogonal. For example info method definition can be used to obtain +with a single command the full definition of a scripted method, and +furthermore, it works as well the same way to obtain e.g. the +definition of a forwarder or an alias.

+

While XOTcl uses different names for info options for objects and +classes (using the prefix "inst" for instance specific method), NX +uses for object specific method the modifier object. For definition +of class object specific methods, use the modifier object as usual.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# n.a.
+
+
/cls/ info method definition /methodName/
+/obj/ info object method definition /methodName/
+
+
/cls/ info instbody /methodName/
+/obj/ info body /methodName/
+
+
/cls/ info method body /methodName/
+/obj/ info object method body /methodName/
+
+
/cls/ info instargs /methodName/
+/obj/ info args /methodName/
+
+
/cls/ info method args /methodName/
+/obj/ info object method args /methodName/
+
+
/cls/ info instnonposargs /methodName/
+/obj/ info object method args /methodName/
+
+
/cls/ info method parameter /methodName/
+/obj/ info object method parameter /methodName/
+
+
/cls/ info instdefault /methodName/
+/obj/ info default /methodName/
+
+
# not needed, part of
+# "info ?object? method parameter"
+
+
/cls/ info instpre /methodName/
+/obj/ info pre /methodName/
+
+
/cls/ info method precondition /methodName/
+/obj/ info object method precondition /methodName/
+
+
/cls/ info instpost /methodName/
+/obj/ info post /methodName/
+
+
/cls/ info method postcondition /methodName/
+/obj/ info object method postcondition /methodName/
+
+

Another powerful introspection option in NX is info ?object? method +syntax which obtains a representation of the parameters of a +method in the style of Tcl man pages (regardless of the kind of +method).

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# n.a.
+
+
/cls/ info method syntax /methodName/
+/obj/ info object method syntax /methodName/
+
+
+
+

2.6.8. List Configure Parameters

+

The way, how newly created objects can be configured is determined in NX +via properties. The configuration happens during creation via the +methods create or new or during runtime via configure. These +methods have therefore virtual argument lists, depending on the object +or class on which they are applied.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# n.a.
+
+
# Return the parameters applicable to
+# the create method of a certain class.
+# class can be configured. A pattern can
+# be used to filter the results.
+
+/cls/ info lookup parameters create ?/pattern/?
+
+# Return in the result in documentation syntax
+
+/cls/ info lookup syntax create ?/pattern/?
+
+# "info lookup parameters configure" returns
+# parameters available for configuring the
+# current object  (might contain object
+# specific information)
+
+/obj/ info lookup parameters configure ?pattern?
+
+# "info lookup configure syntax" returns syntax of
+# a call to configure in the Tcl parameter syntax
+
+/obj/ info lookup syntax configure
+
+# Obtain information from a parameter
+# (as e.g. returned from "info lookup
+# parameters configure").
+
+nsf::parameter::info name /parameter/
+nsf::parameter::info syntax /parameter/
+nsf::parameter::info type /parameter/
+
+
+
+

2.6.9. List Variable Declarations (property and variable)

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# obtain parameter definitions defined
+# for a class
+/cls/ info parameter
+
+
# "info variables" returns handles of
+# properties and variables defined by this
+# class or object
+
+/cls/ info variables ?pattern?
+/obj/ info object variables ?pattern?
+
+# "info lookup variables" returns handles
+# of variables and properties applicable
+# for the current object (might contain
+# object specific information)
+
+/obj/ info lookup variables /pattern/
+
+# "info variable" lists details about a
+# single property or variable.
+
+/obj/ info variable definition /handle/
+/obj/ info variable name /handle/
+/obj/ info variable parameter /handle/
+
+
+
+

2.6.10. List Slots

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# n.a.
+
+
# Return list of slots objects defined on the
+# object or class
+#
+# -source might be all|application|baseclasses
+# -type is the class of the slot object
+# -closure includes slots of superclasses
+
+/cls/ info slots \
+   ?-type value? ?-closure? ?-source value? ?pattern?
+/obj/ info object slots ?-type ...? ?pattern?
+
+# List reachable slot objects defined for obj
+# -source might be all|application|baseclasses
+# -type is the class of the slot object
+# Returns list of slot objects.
+
+/obj/ info lookup slots \
+   ?-type ...? ?-source ... ?pattern?
+
+# Obtain definition, name or parameter from
+# slot object
+
+/slotobj/ definition
+/slotobj/ name
+/slotobj/ parameter
+
+
+
+

2.6.11. List Filter or Mixins

+

In NX all introspection options for filters are provided via +info filters and all introspection options for mixins are +provided via info mixins.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ info filter ?-guards? ?-order? ?pattern?
+/obj/ info filterguard /name/
+
+
/obj/ info object filters \
+   ?-guards? ?pattern?
+
+
/cls/ info instfilter \
+   ?-guards? ?-order? ?pattern?
+/cls/ info instfilterguard /name/
+
+
/cls/ info filters \
+   ?-guards? ?pattern?
+
+
/obj/ info mixin ?-guards? ?-order ?pattern?
+/obj/ info mixinguard /name/
+
+
/obj/ info object mixins \
+   ?-guards? ?pattern?
+
+
/cls/ info instmixin \
+   ?-guards? ?-order? ?pattern?
+/cls/ info instmixinguard /name/
+
+
/cls/ info mixins \
+   ?-closure? ?-guards? ?-heritage? ?pattern?
+
+
+
+

2.6.12. List definition of methods defined by aliases, setters or forwarders

+

As mentioned earlier, info method definition can be used on every +kind of method. The same call can be used to obtain the definition of +a scripted method, a method-alias, a forwarder or a setter method.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# n.a.
+
+
/cls/ info method definition /methodName/
+/obj/ info object method definition /methodName/
+
+
+
+

2.6.13. List Method-Handles

+

NX supports method-handles to provide means to obtain further +information about a method or to change maybe some properties of a +method. When a method is created, the method creating method returns +the method handle to the created method.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# n.a.
+
+
#
+# List the method handle of the specified method,
+# can be used e.g. for aliases. "handle" is the short
+# form of "definitionhandle".
+#
+/cls/ info method handle /methodName/
+/obj/ info object method handle /methodName/
+#
+# For ensemble methods (method name contains
+# spaces) one can query as well the registration
+# handle, which is the handle to the root of the
+# ensemble; the definition handle points to the
+# leaf of the ensemble.
+#
+/cls/ info method registrationhandle /methodName/
+/obj/ info object method registrationhandle /methodName/
+#
+# For aliases, one can query the original
+# definition via "info method origin"
+#
+/cls/ info method origin /methodName/
+/obj/ info object method origin /methodName/
+
+
+
+

2.6.14. List type of a method

+

The method info ?object? method type is new in NX to obtain the type of the +specified method.

+
+ +++ + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
# n.a.
+
+
/cls/ info method type /methodName/
+/obj/ info object method type /methodName/
+
+
+
+

2.6.15. List the scope of mixin classes

+

NX provides a richer set of introspection options to obtain +information, where mixins classes are mixed into.

+
+ +++ + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/cls/ info mixinof ?-closure? ?pattern?
+
+
# List objects, where /cls/ is a
+# per-object mixin
+
+/cls/ info mixinof -scope object ?-closure? \
+   ?pattern?
+
+
/cls/ info instmixinof ?-closure? ?pattern?
+
+
# List classes, where /cls/ is a per-class mixin
+
+/cls/ info mixinof -scope class ?-closure? \
+   ?pattern?
+
+
# n.a.
+
+
# List objects and classes, where /cls/ is
+# either a per-object or a per-class mixin
+
+/cls/ info mixinof -scope all ?-closure? \
+   ?pattern?
+
+
+
/cls/ info mixinof ?-closure? ?pattern?
+
+
+
+

2.6.16. Check properties of object and classes

+

Similar as noted before, NX uses rather a hierarchical approach of +naming using multiple layers of subcommands).

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ istype /sometype/
+
+
# Check if object is a subtype of some class
+/obj/ info has type /sometype/
+
+
/obj/ ismixin /cls/
+
+
# Check if object has the specified mixin registered
+/obj/ info has mixin /cls/
+
+
/obj/ isclass ?/cls/?
+
+
# Check if object is an NX class
+/obj/ has type ::nx::Class
+
+# Check if object is a class in one of the
+# NSF object systems
+::nsf::is class /obj/
+
+
/obj/ ismetaclass /cls/
+
+
# Check if class is an NX metaclass
+expr {[/cls/ info heritage ::nx::Class] ne ""}
+
+# Check if object is a metaclass in one of the
+# NSF object systems
+::nsf::is metaclass /obj/
+
+
# n.a.
+
+
# Check if object is a baseclass of an object system
+::nsf::is baseclass /obj/
+
+
# n.a.
+
+
# Return name of object (without namespace prefix)
+/obj/ info name
+
+
/obj/ object::exists /obj/
+
+
# Check for existence of object (nsf primitive)
+::nsf::object::exists /obj/
+
+
+
+

2.6.17. Call-stack Introspection

+

Call-stack introspection is very similar in NX and XOTcl. NX uses for +subcommand the term current instead of self, since self has a +strong connotation to the current object. The term proc is renamed +by method.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
self
+
+
self
+
+
+
current object
+
+
self class
+
+
current class
+
+
self args
+
+
current args
+
+
self proc
+
+
current method
+
+
self callingclass
+
+
current calledclass
+
+
self callingobject
+
+
current callingobject
+
+
self callingproc
+
+
current callingmethod
+
+
self calledclass
+
+
current calledclass
+
+
self calledproc
+
+
current calledmethod
+
+
self isnextcall
+
+
current isnextcall
+
+
self next
+
+
# Returns method-handle of the
+# method to be called via "next"
+current next
+
+
self filterreg
+
+
# Returns method-handle of the
+# filter method
+current filterreg
+
+
self callinglevel
+
+
current callinglevel
+
+
self activelevel
+
+
current activelevel
+
+
+
+
+

2.7. Other Predefined Methods

+
+ +++ + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ requireNamespace
+
+
/obj/ require namespace
+
+
# n.a.
+
+
/obj/ require method
+
+
+
+

2.8. Dispatch, Aliases, etc.

+

todo: to be done or omitted

+
+
+

2.9. Assertions

+

In contrary to XOTcl, NX provides no pre-registered methods for +assertion handling. All assertion handling can e performed via the +Next Scripting primitive nsf::method::assertion.

+
+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
XOTcl Next Scripting Language
+
+
/obj/ check /checkoptions/
+
+
::nsf::method::assertion /obj/ check /checkoptions/
+
+
/obj/ info check
+
+
::nsf::method::assertion /obj/ check
+
+
/obj/ invar /conditions/
+
+
::nsf::method::assertion /obj/ object-invar /conditions/
+
+
/obj/ info invar
+
+
::nsf::method::assertion /obj/ object-invar
+
+
/cls/ instinvar /conditions/
+
+
::nsf::method::assertion /cls/ class-invar /conditions/
+
+
/cls/ info instinvar
+
+
::nsf::method::assertion /cls/ class-invar
+
+
/cls/ invar /conditions/
+
+
::nsf::method::assertion /cls/ object-invar /conditions/
+
+
/cls/ info invar
+
+
::nsf::method::assertion /cls/ object-invar
+
+
+
+

2.10. Method Protection

+

As described above, NX supports method +protection via the method modifiers protected and public. A +protected method can be only called from an object of that class, +while public methods can be called from every object. The method +protection can be used to every kind of method, such as e.g. scripted +methods, aliases, forwarders, or accessors. For invocations, +the most specific definition (might be a mixin) is used for +determining the protection.

+
+
+
+
+

3. Incompatibilities between XOTcl 1 and XOTcl 2

+
+
+

3.1. Resolvers

+

The resolvers (variable resolvers, function resolvers) of the Next +Scripting Framework are used as well within XOTcl 2. When variable +names or method names starting with a single colon are used in XOTcl 1 +scripts, conflicts will arise with the resolver. These names must be +replaced.

+
+
+

3.2. Parameters

+

The following changes for parameters could be regarded as bug-fixes.

+
+

3.2.1. Parameter usage without a value

+

In XOTcl 1, it was possible to call a parameter method during object +creation via the dash-interface without a value (in the example below -x).

+
+
+
# XOTcl example
+
+Class Foo -parameter {x y}
+Foo f1 -x -y 1
+

Such cases are most likely mistakes. All parameter configurations in XOTcl 2 require an argument.

+
+
+

3.2.2. Ignored Parameter definitions

+

In XOTcl 1, a more specific parameter definition without a default was ignored +when a more general parameter definition with a default was +present. In the example below, the object b1 contained in XOTcl 1 +incorrectly the parameter x (set via default from Foo), while in +XOTcl 2, the variable won’t be set.

+
+
+
# XOTcl example
+
+Class Foo -parameter {{x 1}}
+Class Bar -superclass Foo -parameter x
+Bar b1
+
+
+

3.2.3. Changing classes and superclasses

+

NX does not define the methods class and superclass (like XOTcl), but allows one to +alter all object/class relations (including +class/superclass/object-mixin/…) +nsf::relation::set. The class and superclass can be certainly queried +in all variants with info class or info superclasses.

+
+
+
# NX example
+
+nx::Class create Foo
+Foo create f1
+
+# now alter the class of object f1
+nsf::relation::set f1 class ::nx::Object
+
+
+

3.2.4. Overwriting procs/methods with objects and vice versa

+

NSF is now more conservative on object/method creation. In contrary to +XOTcl 1 NSF does not allow one to redefined a pre-existing command +(e.g. "set") with an object and vice versa. Like in XOTcl 1, +preexisting objects and classes con be redefined (necessary for +reloading objects/classes in a running interpreter).

+
+
+

3.2.5. Info heritage

+

info heritage returns in XOTcl 1 the transitive superclass +hierarchy, which is equivalent with info superclasses -closure and +therefore not necessary. In XOTcl 2 (and NX), info heritage includes +as well the transitive per-class mixins.

+
+
+
+

3.3. Slots

+

All slot objects (also XOTcl slot objects) are now next-scripting +objects of baseclass ::nx::Slot. The name of the experimental +default-setter initcmd was changed to defaultcmd. Code directly +working on the slots objects has to be adapted.

+
+
+

3.4. Obsolete Commands

+

Parameter-classes were rarely used and have been replaced by the more +general object parametrization. Therefore, cl info parameterclass has +been removed.

+
+
+

3.5. Stronger Checking

+

The Next Scripting Framework performs stronger checking than XOTcl 1 +For example, the requiredness of slots in XOTcl 1 was just a +comment, while XOTcl 2 enforces it.

+
+
+

3.6. Exit Handlers

+

The exit handler interface changed from a method of ::xotcl::Object +into the Tcl command ::nsf::exithandler:

+
+
+
# NX example
+::nsf::exithandler set|get|unset ?arg?
+
+
+
+
+

+ + + Index: doc/next-tutorial/next-tutorial.html =================================================================== diff -u -r6cbeef2d45ae090cf57de7703e0b480125e277b1 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- doc/next-tutorial/next-tutorial.html (.../next-tutorial.html) (revision 6cbeef2d45ae090cf57de7703e0b480125e277b1) +++ doc/next-tutorial/next-tutorial.html (.../next-tutorial.html) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -1,3472 +1,3472 @@ - - - - - -Tutorial for the Next Scripting Language - - - - - + +
+
+
+
+
+
Abstract
+

This document provides a tutorial for the Next Scripting +Language NX.

+
+

The Next Scripting Language (NX) is a highly flexible object oriented +scripting language based on Tcl [Ousterhout 1990]. NX is a successor +of XOTcl 1 [Neumann and Zdun 2000a] and was developed based on 10 +years of experience with XOTcl in projects containing several hundred +thousand lines of code. While XOTcl was the first language designed to +provide language support for design patterns, the focus of the Next +Scripting Framework and NX is on combining this with Language +Oriented Programming. In many respects, NX was designed to ease the +learning of the language for novices (by using a more mainstream +terminology, higher orthogonality of the methods, less predefined +methods), to improve maintainability (remove sources of common errors) +and to encourage developers to write better structured programs (to +provide interfaces) especially for large projects, where many +developers are involved.

+

The Next Scripting Language is based on the Next Scripting Framework +(NSF) which was developed based on the notion of language oriented +programming. The Next Scripting Frameworks provides C-level support +for defining and hosting multiple object systems in a single Tcl +interpreter. The name of the Next Scripting Framework is derived from +the universal method combinator "next", which was introduced in XOTcl. +The combinator "next" serves as a single instrument for method +combination with filters, per-object and transitive per-class mixin +classes, object methods and multiple inheritance.

+

The definition of NX is fully scripted (e.g. defined in +nx.tcl). The Next Scripting Framework is shipped with three language +definitions, containing NX and XOTcl 2. Most of the existing XOTcl 1 +programs can be used without modification in the Next Scripting +Framework by using XOTcl 2. The Next Scripting Framework requires Tcl +8.5 or newer.

+
+
+
+

1. NX and its Roots

+
+

Object oriented extensions of Tcl have quite a +long history. Two of the most prominent early Tcl based OO languages +were incr Tcl (abbreviated as itcl) and Object Tcl (OTcl +[Wetherall and Lindblad 1995]). While itcl provides a traditional +C++/Java-like object system, OTcl was following the CLOS approach and +supports a dynamic object system, allowing incremental class and +object extensions and re-classing of objects.

+

Extended Object Tcl (abbreviated as XOTcl [Neumann and Zdun 2000a]) +is a successor of OTcl and was the first language providing language +support for design patterns. XOTcl extends OTcl by providing namespace +support, adding assertions, dynamic object aggregations, slots and by +introducing per-object and per-class filters and per-object and +per-class mixins.

+

XOTcl was so far released in more than 30 versions. It is described in +its detail in more than 20 papers and serves as a basis for other +object systems like TclOO [Donal ???]. The scripting language NX and +the Next Scripting Framework [Neumann and Sobernig 2009] extend +the basic ideas of XOTcl by providing support for language-oriented +programming. The the Next Scripting Framework supports multiple +object systems concurrently. Effectively, every object system has +different base classes for creating objects and classes. Therefore, +these object systems can have different interfaces and can +follow different naming conventions for built-in methods. Currently, +the Next Scripting Framework is packaged with three object systems: +NX, XOTcl 2.0, and TclCool (the language introduced by TIP#279).

+
+
+Languages +
+
Figure 1. Language History of the Next Scripting Language
+
+

+

The primary purpose of this document is to introduce NX to beginners. +We expect some prior knowledge of programming languages, and some +knowledge about Tcl. In the following sections we introduce NX by +examples. In later sections we introduce the more advanced concepts of +the language. Conceptually, most of the addressed concepts are very +similar to XOTcl. Concerning the differences between NX and XOTcl, +please refer to the Migration Guide for the Next Scripting Language.

+
+
+
+

2. Introductory Overview Example: Stack

+
+

A classical programming example is the implementation of a stack, which +is most likely familiar to many readers from many introductory +programming courses. A stack is a last-in first-out data structure +which is manipulated via operations like push (add something to the +stack) and pop remove an entry from the stack. These operations are +called methods in the context of object oriented programming +systems. Primary goals of object orientation are encapsulation and +abstraction. Therefore, we define a common unit (a class) that defines +and encapsulates the behavior of a stack and provides methods to a user +of the data structure that abstract from the actual implementation.

+
+

2.1. Define a Class "Stack"

+

In our first example, we define a class named Stack with the methods +push and pop. When an instance of the stack is created (e.g. a +concrete stack s1) the stack will contain an instance variable named +things, initialized with the an empty list.

+
Listing 2: Class Stack

+
+
+
nx::Class create Stack {
+
+   #
+   # Stack of Things
+   #
+
+   :variable things {}
+
+   :public method push {thing} {
+      set :things [linsert ${:things} 0 $thing]
+      return $thing
+   }
+
+   :public method pop {} {
+      set top [lindex ${:things} 0]
+      set :things [lrange ${:things} 1 end]
+      return $top
+   }
+}
+

Typically, classes are defined in NX via nx::Class create, followed +by the name of the new class (here: Stack). The definition of the +stack placed between curly braces and contains here just the method +definitions. Methods of the class are defined via :method followed +by the name of the method, an argument list and the body of the +method, consisting of Tcl and NX statements.

+

When an instance of Stack is created, it will contain an instance +variable named things. If several Stack instances are created, +each of the instances will have their own (same-named but different) +instance variable. The instance variable things is used in our +example as a list for the internal representation of the stack. We +define in a next step the methods to access and modify this list +structure. A user of the stack using the provided methods does not +have to have any knowledge about the name or the structure of the +internal representation (the instance variable things).

+

The method push receives an argument thing which should be placed +on the stack. Note that we do not have to specify the type of the +element on the stack, so we can push strings as well as numbers or +other kind of things. When an element is pushed, we add this element +as the first element to the list things. We insert the element using +the Tcl command linsert which receives the list as first element, +the position where the element should be added as second and the new +element as third argument. To access the value of the instance +variable we use Tcl’s dollar operator followed by the name. The +names of instance variables are preceded with a colon :. Since the +name contains a non-plain character, Tcl requires us to put braces +around the name. The command linsert and its arguments are placed +between square brackets. This means that the function linsert is called and +a new list is returned, where the new element is inserted at the first +position (index 0) in the list things. The result of the linsert +function is assigned again to the instance variable things, which is +updated this way. Finally the method push returns the pushed thing +using the return statement.

+

The method pop returns the most recently stacked element and removes +it from the stack. Therefore, it takes the first element from the list +(using the Tcl command lindex), assigns it to the method-scoped +variable top, removes the element from the instance variable +things (by using the Tcl command lrange) and returns the value +popped element top.

+

This finishes our first implementation of the stack, more enhanced +versions will follow. Note that the methods push and pop are +defined as public; this means that these methods can be +used from all other objects in the system. Therefore, these methods +provide an interface to the stack implementation.

+
Listing 3: Using the Stack

+
+
+
#!/usr/bin/env tclsh
+package require nx
+
+nx::Class create Stack {
+
+   #
+   # Stack of Things
+   #
+   ....
+}
+
+Stack create s1
+s1 push a
+s1 push b
+s1 push c
+puts [s1 pop]
+puts [s1 pop]
+s1 destroy
+

Now we want to use the stack. The code snippet in Listing 3 shows how to use the class Stack in a script. +Since NX is based on Tcl, the script will be called with the Tcl shell +tclsh. In the Tcl shell we have to require package nx to use the +Next Scripting Framework and NX. The next lines contain the definition +of the stack as presented before. Of course, it is as well possible to +make the definition of the stack an own package, such we could simple +say package require stack, or to save the definition of a stack +simply in a file and load it via source.

+

In line 12 we create an instance of the stack, namely the stack object +s1. The object s1 is an instance of Stack and has therefore +access to its methods. The methods like push or pop can be invoked +via a command starting with the object name followed by the +method name. In lines 13-15 we push on the stack the values a, then +b, and c. In line 16 we output the result of the pop method +using the Tcl command puts. We will see on standard output the +value+c+ (the last stacked item). The output of the line 17 is the +value b (the previously stacked item). Finally, in line 18 we +destroy the object. This is not necessary here, but shows the life +cycle of an object. In some respects, destroy is the counterpart of +create from line 12.

+
+
+object-class-appclass.png +
+
Figure 4. Class and Object Diagram
+
+

+

Figure 4 shows the actual class and +object structure of the first Stack example. Note that the common +root class is nx::Object that contains methods for all objects. +Since classes are as well objects in NX, nx::Class is a +specialization of nx::Object. nx::Class provides methods for +creating objects, such as the method create which is used to create +objects (and classes as well).

+
+
+

2.2. Define an Object Named "stack"

+

The definition of the stack in Listing 2 +follows the traditional object oriented approach, found in +practically every object oriented programming language: Define a class +with some methods, create instances from this class, and use the +methods defined in the class in the instances of the class.

+

In our next example, we introduce generic objects and object +specific methods. With NX, we can define generic objects, which are +instances of the most generic class nx::Object (sometimes called +common root class). nx::Object is predefined and contains a +minimal set of methods applicable to all NX objects. In this example, +we define a generic object named stack and provide methods for this +object. The methods defined above were methods provided by a class for +objects. Now we define object specific methods, which are methods +applicable only to the object for which they are defined.

+
Listing 5: Object stack

+
+
+
nx::Object create stack {
+
+   :object variable things {}
+
+   :public object method push {thing} {
+      set :things [linsert ${:things} 0 $thing]
+      return $thing
+   }
+
+   :public object method pop {} {
+      set top [lindex ${:things} 0]
+      set :things [lrange ${:things} 1 end]
+      return $top
+   }
+}
+

The example in Listing 5 defines the +object stack in a very similar way as the class Stack. But the +following points are different.

+
    +
  • +

    +First, we use nx::Object instead of nx::Class to denote + that we want to create a generic object, not a class. +

    +
  • +
  • +

    +We use :object variable to define the variable things just for + this single instance (the object stack). +

    +
  • +
  • +

    +The definition for the methods push and pop are the same as + before, but here we defined these with object method. Therefore, + these two methods push and pop are object-specific. +

    +
  • +
+

In order to use +the stack, we can use directly the object stack in the same way as +we have used the object s1 in Listing 3 +the class diagram for this the object stack.

+
+
+object-stack.png +
+
Figure 6. Object stack
+
+

+

A reader might wonder when to use a class Stack or rather an object +stack. A big difference is certainly that one can define easily +multiple instances of a class, while the object is actually a +single, tailored entity. The concept of the object stack is similar to a module, +providing a certain functionality via a common interface, without +providing the functionality to create multiple instances. The reuse of +methods provided by the class to objects is as well a difference. If +the methods of the class are updated, all instances of the class will +immediately get the modified behavior. However, this does not mean that +the reuse for the methods of stack is not possible. NX allows for +example to copy objects (similar to prototype based languages) or to +reuse methods via e.g. aliases (more about this later).

+

Note that we use capitalized names for classes and lowercase names for +instances. This is not required and a pure convention making it easier +to understand scripts without much analysis.

+
+
+

2.3. Implementing Features using Mixin Classes

+

So far, the definition of the stack methods was pretty minimal. +Suppose, we want to define "safe stacks" that protect e.g. against +stack under-runs (a stack under-run happens, when more pop than +push operations are issued on a stack). Safety checking can be +implemented mostly independent from the implementation details of the +stack (usage of internal data structures). There are as well different +ways of checking the safety. Therefore we say that safety checking is +orthogonal to the stack core implementation.

+

With NX we can define stack-safety as a separate class using methods +with the same names as the implementations before, and "mix" this +behavior into classes or objects. The implementation of Safety in +stack under-runs and to issue error messages, when this happens.

+
Listing 7: Class Safety

+
+
+
nx::Class create Safety {
+
+  #
+  # Implement stack safety by defining an additional
+  # instance variable named "count" that keeps track of
+  # the number of stacked elements. The methods of
+  # this class have the same names and argument lists
+  # as the methods of Stack; these methods "shadow"
+  # the methods of class Stack.
+  #
+
+  :variable count 0
+
+  :public method push {thing} {
+    incr :count
+    next
+  }
+
+  :public method pop {} {
+    if {${:count} == 0} { error "Stack empty!" }
+    incr :count -1
+    next
+  }
+}
+

Note that all the methods of the class Safety end with next. +This command is a primitive command of NX, which calls the +same-named method with the same argument list as the current +invocation.

+

Assume we save the definition of the class Stack in a file named +Stack.tcl and the definition of the class Safety in a file named +Safety.tcl in the current directory. When we load the classes +Stack and Safety into the same script (see the terminal dialog in +e.g. a certain stack s2 as a safe stack, while all other stacks +(such as s1) might be still "unsafe". This can be achieved via the +option -mixin at the object creation time (see line 9 in +option -mixin mixes the class Safety into the new instance s2.

+
Listing 8: Using the Class Safety

+
+
+
% package require nx
+2.0
+% source Stack.tcl
+::Stack
+% source Safety.tcl
+::Safety
+% Stack create s1
+::s1
+% Stack create s2 -object-mixin Safety
+::s2
+% s2 push a
+% s2 pop
+a
+% s2 pop
+Stack empty!
+
+% s1 info precedence
+::Stack ::nx::Object
+
+% s2 info precedence
+::Safety ::Stack ::nx::Object
+

When the method push of s2 is called, first the method of the +mixin class Safety will be invoked that increments the counter and +continues with next to call the shadowed method, here the method +push of the Stack implementation that actually pushes the item. +The same happens, when s2 pop is invoked, first the method of +Safety is called, then the method of the Stack. When the stack is +empty (the value of count reaches 0), and pop is invoked, the +mixin class Safety generates an error message (raises an exception), +and does not invoke the method of the Stack.

+

The last two commands in +Listing 8 +use introspection to query for the objects +s1 and s2 in which order the involved classes are processed. This +order is called the precedence order and is obtained via info +precedence. We see that the mixin class Safety is only in use for +s2, and takes there precedence over Stack. The common root class +nx::Object is for both s1 and s2 the base class.

+
+
+per-object-mixin.png +
+
Figure 9. Per-object Mixin
+
+

+

Note that in Listing 8, +the class Safety is only mixed into a single object (here +s2), therefore we refer to this case as a per-object mixin. +Figure 9 shows the class +diagram, where the class Safety is used as a per-object mixin for +s2.

+

The mixin class Safety can be used as well in other ways, such as e.g. for +defining classes of safe stacks:

+
Listing 10: Class SafeStack

+
+
+
#
+# Create a safe stack class by using Stack and mixin
+# Safety
+#
+nx::Class create SafeStack -superclasses Stack -mixins Safety
+
+SafeStack create s3
+

The difference of a per-class mixin and a per-object mixin is that +the per-class mixin is applicable to all instances of the +class. Therefore, we call these mixins also sometimes instance mixins. +In our example in Listing 10, +Safety is mixed into the definition of +SafeStack. Therefore, all instances of the class SafeStack (here +the instance s3) will be using the safety definitions.

+
+
+per-class-mixin.png +
+
Figure 11. Per-class Mixin
+
+

+

Figure 11 shows the class diagram +for this definition. +Note that we could use Safety as well as a per-class mixin on +Stack. In this case, all stacks would be safe stacks and we could +not provide a selective feature selection (which might be perfectly +fine).

+
+
+

2.4. Define Different Kinds of Stacks

+

The definition of Stack is generic and allows all kind of elements +to be stacked. Suppose, we want to use the generic stack definition, +but a certain stack (say, stack s4) should be a stack for integers +only. This behavior can be achieved by the same means as introduced +already in Listing 5, namely +object-specific methods.

+
Listing 12: Object Integer Stack

+
+
+
Stack create s4 {
+
+  #
+  # Create a stack with a object-specific method
+  # to check the type of entries
+  #
+
+  :public object method push {thing:integer} {
+    next
+  }
+}
+

The program snippet in Listing 12 defines an instance s4 of the class +Stack and provides an object specific method for push to implement +an integer stack. The method pull is the same for the integer stack +as for all other stacks, so it will be reused as usual from the class +Stack. The object-specific method push of s4 has a value +constraint in its argument list (thing:integer) that makes sure +that only integers can be stacked. In case the argument is not an +integer, an exception will be raised. Of course, one could perform the +value constraint checking as well in the body of the method proc by +accepting an generic argument and by performing the test for the value +in the body of the method. In the case, the passed value is an +integer, the push method of Listing 12 calls next, and therefore calls the +shadowed generic definition of push as provided by Stack.

+
Listing 13: Class IntegerStack

+
+
+
nx::Class create IntegerStack -superclass Stack {
+
+  #
+  # Create a Stack accepting only integers
+  #
+
+  :public method push {thing:integer} {
+    next
+  }
+}
+

An alternative approach is shown in +Listing 13, where the class +IntegerStack is defined, using the same method definition +as s4, this time on the class level.

+
+
+

2.5. Define Object Specific Methods on Classes

+

In our previous examples we defined methods provided by classes +(applicable for their instances) and object-specific methods (methods +defined on objects, which are only applicable for these objects). In +this section, we introduce methods that are defined on the class +objects. Such methods are sometimes called class methods or +static methods.

+

In NX classes are objects, they are specialized objects with +additional methods. Methods for classes are often used for managing +the life-cycles of the instances of the classes (we will come to this +point in later sections in more detail). Since classes are objects, we +can use exactly the same notation as above to define class methods by +using object method. The methods defined on the class object are +in all respects identical with object specific methods shown in the +examples above.

+
Listing 14: Class Stack2

+
+
+
nx::Class create Stack2 {
+
+   :public object method available_stacks {} {
+      return [llength [:info instances]]
+   }
+
+   :variable things {}
+
+   :public method push {thing} {
+      set :things [linsert ${:things} 0 $thing]
+      return $thing
+   }
+
+   :public method pop {} {
+      set top [lindex ${:things} 0]
+      set :things [lrange ${:things} 1 end]
+      return $top
+   }
+}
+
+Stack2 create s1
+Stack2 create s2
+
+puts [Stack2 available_stacks]
+

The class Stack2 in Listing 14 consists of the +earlier definition of the class Stack and is extended by the +class-specific method available_stacks, which returns the +current number of instances of the stack. The final command puts +(line 26) prints 2 to the console.

+
+
+stack2.png +
+
Figure 15. Stack2
+
+

+

The class diagram in Figure 15 shows the +diagrammatic representation of the class object-specific method +available_stacks. Since every class is a specialization of the +common root class nx::Object, the common root class is often omitted +from the class diagrams, so it was omitted here as well in the diagram.

+
+
+
+
+

3. Basic Language Features of NX

+
+
+

3.1. Variables and Properties

+

In general, NX does not need variable declarations. It allows one to +create or modify variables on the fly by using for example the Tcl +commands set and unset. Depending on the variable name (or more +precisely, depending on the variable name’s prefix consisting of +colons ":") a variable is either local to a method, or it is an +instance variable, or a global variable. The rules are:

+
    +
  • +

    +A variable without any colon prefix refers typically to a method + scoped variable. Such a variable is created during the invocation + of the method, and it is deleted, when the method ends. In the + example below, the variable a is method scoped. +

    +
  • +
  • +

    +A variable with a single colon prefix refers to an instance + variable. An instance variable is part of the object; when the + object is destroyed, its instance variables are deleted as well. In the + example below, the variable b is an instance variable. +

    +
  • +
  • +

    +A variable with two leading colons refers to a global variable. The + lifespan of a globale variable ends when the variable is explicitly + unset or the script terminates. Variables, which are placed in Tcl + namespaces, are also global variables. In the example below, the + variable c is a global variable. +

    +
  • +
+
Listing 16: Scopes of Variables

+
+
+
nx::Class create Foo {
+
+  :public method foo args {...}
+    # "a" is a method scoped variable
+    set a 1
+    # "b" is an Instance variable
+    set :b 2
+    # "c" is a global variable/namespaced variable
+    set ::c 3
+  }
+}
+

Listing 16 shows a method foo +of some class Foo referring to differently scoped variables.

+
+

3.1.1. Properties: Configurable Instance Variables

+

As described above, there is no need to declare instance variables in +NX. In many cases, a developer might want to define some value +constraints for variables, or to provide defaults, or to make +variables configurable upon object creation. Often, variables are +"inherited", meaning that the variables declared in a general class +are also available in a more specialized class. For these purposes NX +provides variable handlers responsible for the management of +instance variables. We distinguish in NX between configurable +variables (called property) and variables that are not configurable +(called variable).

+
+
+

A property is a definition of a configurable instance variable.

+
+

The term configurable means that (a) one can provide at creation time of +an instance a value for this variable, and (b), one can query the +value via the accessor function cget and (c), one can change the +value of the variable via configure at runtime. Since the general +accessor function cget and configure are available, an application +developer does not have to program own accessor methods. When value +checkers are provided, each time, the value of the variable is to be +changed, the constrained are checked as well.

+
+
+person-student.png +
+
Figure 17. Classes Person and Student
+
+

+

The class diagram above defines the classes Person and +Student. For both classes, configurable instance variable are +specified by defining these as properties. The listing below shows +an implementation of this conceptual model in NX.

+
Listing 18: Properties

+
+
+
#
+# Define a class Person with properties "name"
+# and "birthday"
+#
+nx::Class create Person {
+  :property name:required
+  :property birthday
+}
+
+#
+# Define a class Student as specialization of Person
+# with additional properties
+#
+nx::Class create Student -superclass Person {
+  :property matnr:required
+  :property {oncampus:boolean true}
+}
+
+#
+# Create instances using configure parameters
+# for the initialization
+#
+Person create p1 -name Bob
+Student create s1 -name Susan -matnr 4711
+
+# Access property value via accessor method
+puts "The name of s1 is [s1 cget -name]"
+

By defining name and birthday as properties of Person, NX makes +these configurable. When we create an instance of Person named +p1, we can provide a value for e.g. the name by specifying -name +during creation. The properties result in non-positional configure parameters +which can be provided in any order. In our listing, we create an instance of +Person using the configure parameter name and provide the value of +Bob to the instance variable name.

+

The class Student is defined as a specialization of Person with +two additional properties: matnr and oncampus. The property +matnr is required (it has to be provided, when an instance of this +class is created), and the property oncampus is boolean, and is per +default set to true. Note that the class Student inherits the +properties of Person. So, Student has four properties in total.

+

The property definitions provide the configure parameters for +instance creation. Many other languages require such parameters to be +passed via arguments of a constructor, which is often error prone, +when values are to be passed to superclasses. Also in dynamic +languages, the relationships between classes can be easily changed, +and different superclasses might have different requirements in their +constructors. The declarative approach in NX reduces the need for +tailored constructor methods significantly.

+

Note that the property matnr of class Student is required. This +means, that if we try to create an instance of Student, a runtime +exception will be triggered. The property oncamups is boolean and +contains a default value. Providing a default value means that +whenever we create an instance of this class the object will contain +such an instance variable, even when we provide no value via the +configure parameters.

+

In our listing, we create an instance of Student using the two +configure parameters name and matnr. Finally, we use method cget +to obtain the value of the instance variable name of object s1.

+
+
+

3.1.2. Non-configurable Instance Variables

+

In practice, not all instance variables should be configurable. But +still, we want to be able to provide defaults similar to +properties. To define non-configurable instance variables the +predefined method variable can be used. Such instance variables are +often used for e.g. keeping the internal state of an object. The +usage of variable is in many respects similar to property. One +difference is, that property uses the same syntax as for method +parameters, whereas variable receives the default value as a +separate argument (similar to the variable command in plain +Tcl). The introductory Stack example in Listing 2 uses already the method variable.

+
Listing 19: Declaring Variables

+
+
+
nx::Class create Base {
+  :variable x 1
+  # ...
+}
+
+nx::Class create Derived -superclass Base {
+  :variable y 2
+  # ...
+}
+
+# Create instance of the class Derived
+Derived create d1
+
+# Object d1 has instance variables
+# x == 1 and y == 2
+

Note that the variable definitions are inherited in the same way as +properties. The example in Listing 19 shows a +class Derived that inherits from Base. When an instance d1 is +created, it will contain the two instance variables x and y. +Note that the variable declarations from property and variable are +used to initialize (and to configure) the instances variables of an object.

+
Listing 20: Setting Variables in the Constructor

+
+
+
nx::Class create Base2 {
+ # ...
+ :method init {} {
+   set :x 1
+   # ....
+ }
+}
+
+nx::Class create Derived2 -superclass Base2 {
+ # ...
+ :method init {} {
+   set :y 2
+   next
+   # ....
+ }
+}
+
+# Create instance of the class Derived2
+Derived2 create d2
+

In many other object oriented languages, the instance variables are +initialized solely by the constructor (similar to class Derived2 in +Listing 20). This approach is certainly +also possible in NX. Note that the approach using constructors +requires an explicit method chaining between the constructors and is +less declarative than the approach in NX using property and variable.

+

Both, property and variable provide much more functionalities. One +can for example declare public, protected or private accessor +methods, or one can define variables to be incremental (for +e.g. adding values to a list of values), or one can define variables +specific behavior.

+
+
+
+

3.2. Method Definitions

+

The basic building blocks of an object oriented program are object and +classes, which contain named pieces of code, the methods.

+
+
+

Methods are subroutines (pieces of code) associated with objects +and/or classes. A method has a name, receives optionally arguments +during invocation and returns a value.

+
+

Plain Tcl provides subroutines, which are not associated with objects +or classes. Tcl distinguishes between +proc+s (scripted subroutines) +and commands (system-languages implemented subroutines).

+

Methods might have different scopes, defining, on which kind of +objects these methods are applicable to. These are described in more +detail later on. For the time being, we deal here with methods defined +on classes, which are applicable for the instance of these classes.

+
+

3.2.1. Scripted Methods

+

Since NX is a scripting language, most methods are most likely +scripted methods, in which the method body contains Tcl code.

+
Listing 21: Scripted method

+
+
+
# Define a class
+nx::Class create Dog {
+
+  # Define a scripted method for the class
+  :public method bark {} {
+    puts "[self] Bark, bark, bark."
+  }
+}
+
+# Create an instance of the class
+Dog create fido
+
+# The following line prints "::fido Bark, bark, bark."
+fido bark
+

In the example above we create a class Dog with a scripted method +named bark. The method body defines the code, which is executed when +the method is invoked. In this example, the method bar prints out a +line on the terminal starting with the object name (this is determined +by the built in command self) followed by "Bark, bark, bark.". This +method is defined on a class and applicable to instances of the class +(here the instance fido).

+
+
+

3.2.2. C-implemented Methods

+

Not all of the methods usable in NX are scripted methods; many +predefined methods are defined in the underlying system language, +which is typically C. For example, in Listing 21 we +used the method create to create the class Dog and to create the +dog instance fido. These methods are implemented in C in the next +scripting framework.

+

C-implemented methods are not only provided by the underlying +framework but might be as well defined by application developers. This +is an advanced topic, not covered here. However, application developer +might reuse some generic C code to define their own C-implemented +methods. Such methods are for example accessors, forwarders and +aliases.

+
+
+

An accessor method is a method that accesses instance +variables of an object. A call to an accessor +without arguments uses the accessor as a getter, obtaining the actual +value of the associated variable. A call to an accessor with an +argument uses it as a setter, setting the value of the associated +variable.

+
+

NX provides support for C-implemented accessor methods. Accessors have +already been mentioned in the section about properties. When +the option -accessor public|protected|private is provided to a +variable or property definition, NX creates automatically a +same-named accessors method.

+
Listing 22: Accessor Methods

+
+
+
nx::Class create Dog {
+ :public method bark {} { puts "[self] Bark, bark, bark." }
+ :method init {} { Tail create [self]::tail}
+}
+
+nx::Class create Tail {
+  :property -accessor public {length:double 5}
+  :public method wag {} {return Joy}
+}
+
+# Create an instance of the class
+Dog create fido
+
+# Use the accessor "length" as a getter, to obtain the value
+# of a property. The following call returns the length of the
+# tail of fido
+fido::tail length get
+
+# Use the accessor "length" as a setter, to alter the value
+# of a property. The following call changes the length of
+# the tail of fido
+fido::tail length set 10
+
+# Proving an invalid values will raise an error
+fido::tail length set "Hello"
+

Listing 22 shows an extended example, where every dog +has a tail. The object tail is created as a subobject of the dog in +the constructor init. The subobject can be accessed by providing the +full name of the subobject fido::tail. The method length is an +C-implemented accessor, that enforces the value constraint (here a +floating point number, since length uses the value constraint +double). Line 25 will therefore raise an exception, since the +provided values cannot be converted to a double number.

+
Listing 23: Forwarder Methods

+
+
+
nx::Class create Dog {
+  :public method bark {} { puts "[self] Bark, bark, bark." }
+  :method init {} {
+    Tail create [self]::tail
+    :public object forward wag [self]::tail wag
+  }
+}
+
+nx::Class create Tail {
+  :property {length 5}
+  :public method wag {} {return Joy}
+}
+
+# Create an instance of the class
+Dog create fido
+
+# The invocation of "fido wag" is delegated to "fido::tail wag".
+# Therefore, the following method returns "Joy".
+fido wag
+

Listing 23 again extends the example by adding a +forwarder named wag to the object (e.g. fido). The forwarder +redirects all calls of the form fido wag with arbitrary arguments to +the subobject fido::tail.

+
+
+

A forwarder method is a +C-implemented method that redirects an invocation for a certain method +to either a method of another object or to some other method of the +same object. Forwarding an invocation of a method to some other +object is a means of delegation.

+
+

The functionality of the forwarder can just as well be implemented as +a scripted method, but for the most common cases, the forward +implementation is more efficient, and the forward method expresses +the intention of the developer.

+

The method forwarder has several options to change e.g. the order of +the arguments, or to substitute certain patterns in the argument list +etc. This will be described in later sections.

+
+
+

3.2.3. Method-Aliases

+
+
+

An alias method is a means to register either an existing method, +or a Tcl proc, or a Tcl command as a method with the provided +name on a class or object.

+
+

In some way, the method alias is a restricted form of a forwarder, +though it does not support delegation to different objects or argument +reordering. The advantage of the method alias compared to a forwarder +is that it has close to zero overhead, especially for aliasing +c-implemented methods.

+
Listing 24: Method-Alias

+
+
+
nx::Class create Dog {
+  :public method bark {} { puts "[self] Bark, bark, bark." }
+
+  # Define a public alias for the method "bark"
+  :public alias warn [:info method handle bark]
+  # ...
+}
+
+# Create an instance of the class
+Dog create fido
+
+# The following line prints "::fido Bark, bark, bark."
+fido warn
+

Listing 24 extends the last example by defining an +alias for the method bark. The example only shows the bare +mechanism. In general, method aliases are very powerful means for +reusing pre-existing functionality. The full object system of NX and +XOTcl2 is built from aliases, reusing functionality provided by the +next scripting framework under different names. Method aliases +are as well a means for implementing traits in NX.

+
+
+
+

3.3. Method Protection

+

All kinds of methods might have different kind of protections in NX. +The call-protection defines from which calling context methods might +be called. The Next Scripting Framework supports as well redefinition +protection for methods.

+

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 foo").

+
+

All kind of method protections are applicable for all kind of methods, +either scripted or C-implemented.

+

The distinction between public and protected leads to interfaces for +classes and objects. Public methods are intended for consumers of +these entities. Public methods define the intended ways of providing +methods for external usages (usages, from other objects or +classes). Protected methods are intended for the implementor of the +class or subclasses and not for public usage. The distinction between +protected and public reduces the coupling between consumers and the +implementation, and offers more flexibility to the developer.

+
Listing 25: Protected Methods

+
+
+
nx::Class create Foo {
+
+  # Define a public method
+  :public method foo {} {
+    # ....
+    return [:helper]
+  }
+
+  # Define a protected method
+  :method helper {} {
+     return 1
+  }
+}
+
+# Create an instance of the class:
+Foo create f1
+
+# The invocation of the public method "foo" returns 1
+f1 foo
+
+# The invocation of the protected method "helper" raises an error:
+f1 helper
+

The example above uses :protected method helper …. We could have +used here as well :method helper …, since the default method +call-protection is already protected.

+

The method call-protection of private goes one step further and +helps to hide implementation details also for implementors of +subclasses. Private methods are a means for avoiding unanticipated name +clashes. Consider the following example:

+
Listing 26: Private Methods

+
+
+
nx::Class create Base {
+  :private method helper {a b} {expr {$a + $b}}
+  :public method foo     {a b} {: -local helper $a $b}
+}
+
+nx::Class create Sub -superclass Base {
+  :public method bar     {a b} {: -local helper $a $b}
+  :private method helper {a b} {expr {$a * $b}}
+  :create s1
+}
+
+s1 foo 3 4     ;# returns 7
+s1 bar 3 4     ;# returns 12
+s1 helper 3 4  ;# raises error: unable to dispatch method helper
+

The base class implements a public method foo using the helper +method named helper. The derived class implements a as well a public +method bar, which is also using a helper method named helper. When +an instance s1 is created from the derived class, the method foo +is invoked which uses in turn the private method of the base +class. Therefore, the invocation s1 foo 3 4 returns its sum. If +the local flag had not beed used in helper, s1 would +have tried to call the helper of Sub, 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 next-path, etc.

+

By using the -local flag at the call site it is possible to invoke +only the local definition of the method. If we would call the method +without this flag, the resolution order would be the standard +resolution order, starting with filters, mixins, 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 therefore internally a variable with a different name to avoid +unintended interactions. The variable should be accessed via the +private accessor, which can be invoked with the -local flag. In the +following example class D introduces a private property with the +same name as a property in the superclass.

+
Listing 27: Private Properties

+
+
+
#
+# Define a class C with a property "x" and a public accessor
+#
+nx::Class create C {
+  :property -accessor public {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 {
+  :property -accessor private {x d}
+  :public method bar {p} {return [: -local $p get]}
+}
+
+#
+# The private and public (or protected) properties
+# define internally separate variable that do not
+# conflict.
+#
+D create d1
+puts [d1 x get]   ;# 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).

+
+
+

3.4. Applicability of Methods

+

As defined above, a method is a subroutine defined on an object or +class. This object (or class) contains the method. If the object (or +class) is deleted, the contained methods will be deleted as well.

+
+

3.4.1. Instance Methods

+
+
+

Typically, methods are defined on a class, and the methods defined on the +class are applicable to the instances (direct or indirect) of this +class. These methods are called instance methods.

+
+

In the following example method, foo is an instance method defined +on class C.

+
Listing 28: Methods applicable for instances

+
+
+
nx::Class create C {
+  :public method foo {} {return 1}
+  :create c1
+}
+
+# Method "foo" is defined on class "C"
+# and applicable to the instances of "C"
+c1 foo
+

There are many programming languages that only allow these types of methods. +However, NX also allows methods to be defined on objects.

+
+
+

3.4.2. Object Methods

+
+
+

Methods defined on objects are object methods. Object +methods are only applicable on the object, on which they are defined. +Object methods cannot be inherited from other objects.

+
+

The following example defines an object method bar on the +instance c1 of class C, and as well as the object specific method +baz defined on the object o1. An object method is defined +via object method.

+

Note that we can define a object method that shadows (redefines) +for this object methods provided from classes.

+
Listing 29: Object Method

+
+
+
nx::Class create C {
+  :public method foo {} {return 1}
+  :create c1 {
+     :public object method foo {} {return 2}
+     :public object method bar {} {return 3}
+  }
+}
+
+# Method "bar" is an object specific method of "c1"
+c1 bar
+
+# object-specific method "foo" returns 2
+c1 foo
+
+# Method "baz" is an object specific method of "o1"
+nx::Object create o1 {
+  :public object method baz {} {return 4}
+}
+o1 baz
+
+
+

3.4.3. Class Methods

+
+
+

A class method is a method defined on a class, which is only +applicable to the class object itself. The class method is actually +an object method of the class object.

+
+

In NX, all classes are objects. Classes are in NX special kind of +objects that have e.g. the ability to create instances and to provide +methods for the instances. Classes manage their instances. The general +method set for classes is defined on the meta-classes (more about +this later).

+

The following example defines a public class method bar on class +C. The class method is specified by using the modifier object in +front of method in the method definition command.

+
Listing 30: Class Methods

+
+
+
nx::Class create C {
+  #
+  # Define a class method "bar" and an instance
+  # method "foo"
+  #
+  :public object method bar {} {return 2}
+  :public method foo {} {return 1}
+
+  #
+  # Create an instance of the current class
+  #
+  :create c1
+}
+
+# Method "bar" is a class method of class "C"
+# therefore applicable on the class object "C"
+C bar
+
+# Method "foo" is an instance method of "C"
+# therefore applicable on instance "c1"
+c1 foo
+
+# When trying to invoke the class method on the
+# instance, an error will be raised.
+c1 bar
+

In some other object-oriented programming languages, class methods +are called "static methods".

+
+
+
+

3.5. Ensemble Methods

+

NX provides ensemble methods as a means to structure the method name +space and to group related methods. Ensemble methods are similar in +concept to Tcl’s ensemble commands.

+
+
+

An ensemble method is a form of a hierarchical method consisting of +a container method and sub-methods. The first argument of the +container method is interpreted as a selector (the sub-method). Every +sub-method can be an container method as well.

+
+

Ensemble methods provide a means to group related commands together, +and they are extensible in various ways. It is possible to add +sub-methods at any time to existing ensembles. Furthermore, it is +possible to extend ensemble methods via mixin classes.

+

The following example defines an ensemble method for string. An +ensemble method is defined when the provide method name contains a +space.

+
Listing 31: Ensemble Method

+
+
+
nx::Class create C {
+
+    # Define an ensemble method "string" with sub-methods
+    # "length", "tolower" and "info"
+
+    :public method "string length"  {x} {....}
+    :public method "string tolower" {x} {...}
+    :public method "string info" {x} {...}
+    #...
+    :create c1
+}
+
+# Invoke the ensemble method
+c1 string length "hello world"
+
+
+

3.6. Method Resolution

+

When a method is invoked, the applicable method is searched in the +following order:

+Per-object Mixins -> Per-class Mixins -> Object -> Intrinsic Class Hierarchy +

In the case, no mixins are involved, first the object is searched for +an object method with the given name, and then the class hierarchy +of the object. The method can be defined multiple times on the search +path, so some of these method definitions might be shadowed by the +more specific definitions.

+
Listing 32: Method Resolution with Intrinsic Classes

+
+
+
nx::Class create C {
+  :public method foo {} {
+    return "C foo: [next]"
+  }
+}
+
+nx::Class create D -superclass C {
+
+  :public method foo {} {
+    return "D foo: [next]"
+  }
+
+   :create d1 {
+     :public object method foo {} {
+       return "d1 foo: [next]"
+     }
+   }
+}
+
+# Invoke the method foo
+d1 foo
+# result: "d1 foo: D foo: C foo: "
+
+# Query the precedence order from NX via introspection
+d1 info precedence
+# result: "::D ::C ::nx::Object"
+

Consider the example in +Listing 32. When the method +foo is invoked on object d1, the object method has the highest +precedence and is therefore invoked. The object methods shadows +the same-named methods in the class hierarchy, namely the method foo +of class D and the method foo of class C. The shadowed methods +can be still invoked, either via the primitive next or via method +handles (we used already method handles in the section about method +aliases). In the example above, next calls the shadowed method and +add their results to the results of every method. So, the final result +contains parts from d1, D and C. Note that the topmost next +in method foo of class C shadows no method foo and simply +returns empty (and not an error message).

+

The introspection method info precedence provides information about +the order, in which classes processed during method resolution.

+
Listing 33: Method Resolution with Mixin Classes

+
+
+
nx::Class create M1 {
+  :public method foo {} { return "M1 foo: [next]"}
+}
+nx::Class create M2 {
+  :public method foo {} { return "M2 foo: [next]"}
+}
+
+#
+# "d1" is created based on the definitions of the last example
+#
+# Add the methods from "M1" as per-object mixin to "d1"
+d1 object mixins add M1
+
+#
+# Add the methods from "M2" as per-class mixin to class "C"
+C mixins add M2
+
+# Invoke the method foo
+d1 foo
+# result: "M1 foo: M2 foo: d1 foo: D foo: C foo: "
+
+# Query the precedence order from NX via introspection
+d1 info precedence
+# result: "::M1 ::M2 ::D ::C ::nx::Object"
+

The example in Listing 33 is +an extension of the previous example. We define here two additional +classes M1 and M2 which are used as per-object and per-class +mixins. Both classes define the method foo, these methods shadow +the definitions of the intrinsic class hierarchy. Therefore an +invocation of foo on object d1 causes first an invocation of +method in the per-object mixin.

+
Listing 34: Method Invocation Flags

+
+
+
#
+# "d1" is created based on the definitions of the last two examples,
+# the mixins "M1" and "M2" are registered.
+#
+# Define a public object method "bar", which calls the method
+# "foo" which various invocation options:
+#
+d1 public object method bar {} {
+   puts [:foo]
+   puts [: -local foo]
+   puts [: -intrinsic foo]
+   puts [: -system foo]
+}
+
+# Invoke the method "bar"
+d1 bar
+

In the first line of the body of method bar, the method foo is +called as usual with an implicit receiver, which defaults to the +current object (therefore, the call is equivalent to d1 foo). The +next three calls show how to provide flags that influence the method +resolution. The flags can be provided between the colon and the method +name. These flags are used rather seldom but can be helpful in some +situations.

+

The invocation flag -local means that the method has to be resolved +from the same place, where the current method is defined. Since the +current method is defined as a object method, foo is resolved as +a object method. The effect is that the mixin definitions are +ignored. The invocation flag -local was already introduced int the +section about method protection, where it was used to call private +methods.

+

The invocation flag -intrinsic means that the method has to be resolved +from the intrinsic definitions, meaning simply without mixins. The +effect is here the same as with the invocation flag -local.

+

The invocation flag -system means that the method has to be resolved +from basic - typically predefined - classes of the object system. This +can be useful, when script overloads system methods, but still want to +call the shadowed methods from the base classes. In our case, we have +no definitions of foo on the base clases, therefore an error message +is returned.

+

The output of Listing 34 is:

+
+
+
   M1 foo: M2 foo: d1 foo: D foo: C foo:
+   d1 foo: D foo: C foo:
+   d1 foo: D foo: C foo:
+   ::d1: unable to dispatch method 'foo'
+
+
+
+

3.7. Parameters

+

NX provides a generalized mechanism for passing values to either +methods (we refer to these as method parameters) or to objects +(these are called configure parameters). Both kind of parameters +might have different features, such as:

+
    +
  • +

    +Positional and non-positional parameters +

    +
  • +
  • +

    +Required and non-required parameters +

    +
  • +
  • +

    +Default values for parameters +

    +
  • +
  • +

    +Value-checking for parameters +

    +
  • +
  • +

    +Multiplicity of parameters +

    +
  • +
+

TODO: complete list above and provide a short summary of the section

+

Before we discuss method and configure parameters in more detail, we +describe the parameter features in the subsequent sections based on +method parameters.

+
+

3.7.1. Positional and Non-Positional Parameters

+

If the position of a parameter in the list of formal arguments +(e.g. passed to a function) is significant for its meaning, this is a +positional parameter. If the meaning of the parameter is independent +of its position, this is a non-positional parameter. When we call a +method with positional parameters, the meaning of the parameters (the +association with the argument in the argument list of the method) is +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.

+
Listing 35: Positional and Non-Positional Method Parameters

+
+
+
nx::Object create o1 {
+
+  #
+  # Method foo has positional parameters:
+  #
+  :public object method foo {x y} {
+    puts "x=$x y=$y"
+  }
+
+  #
+  # Method bar has non-positional parameters:
+  #
+  :public object method bar {-x -y} {
+    puts "x=$x y=$y"
+  }
+
+  #
+  # Method baz has non-positional and
+  # positional parameters:
+  #
+  :public object method baz {-x -y a} {
+    puts "x? [info exists x] y? [info exists y] a=$a"
+  }
+}
+
+# invoke foo (positional parameters)
+o1 foo 1 2
+
+# invoke bar (non-positional parameters)
+o1 bar -y 3 -x 1
+o1 bar -x 1 -y 3
+
+# invoke baz (positional and non-positional parameters)
+o1 baz -x 1 100
+o1 baz 200
+o1 baz -- -y
+

Consider the example in Listing 35. The method +foo has the argument list x y. This means that the first argument +is passed in an invocation like o1 foo 1 2 to x (here, the value +1), and the second argument is passed to y (here the value 2). +Method bar has in contrary just with non-positional arguments. Here +we pass the names of the parameter together with the values. In the +invocation o1 bar -y 3 -x 1 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 +Listing 35) in both cases the variables x +and y in the body of the method bar get the same values assigned +(x becomes 1, y becomes 3).

+

It is certainly possible to combine positional and non-positional +arguments. Method baz provides two non-positional parameter (-y +and -y) and one positional parameter (namely a). The invocation in +line 34 passes the value of 1 to x and the value of 100 to a. +There is no value passed to y, therefore value of y will be +undefined in the body of baz, info exists y checks for the +existence of the variable y and returns 0.

+

The invocation in line 35 passes only a value to the positional +parameter. A more tricky case is in line 36, where we want to pass +-y as a value to the positional parameter a. The case is more +tricky since syntactically the argument parser might consider -y as +the name of one of the non-positional parameter. Therefore we use -- +(double dash) to indicate the end of the block of the non-positional +parameters and therefore the value of -y is passed to a.

+
+
+

3.7.2. Optional and Required Parameters

+

Per default positional parameters are required, and non-positional +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.

+
Listing 36: Optional and Required Method Parameters

+
+
+
nx::Object create o2 {
+
+  #
+  # Method foo has one required and one optional
+  # positional parameter:
+  #
+  :public object method foo {x:required y:optional} {
+    puts "x=$x y? [info exists y]"
+  }
+
+  #
+  # Method bar has one required and one optional
+  # non-positional parameter:
+  #
+  :public object method bar {-x:required -y:optional} {
+    puts "x=$x y? [info exists y]"
+  }
+}
+
+# invoke foo (one optional positional parameter is missing)
+o2 foo 1
+

The example in Listing 36 defined method foo +with one required and one optional positional parameter. For this +purpose we use the parameter options required and optional. The +parameter options are separated from the parameter name by a colon. If +there are multiple parameter options, these are separated by commas +(we show this in later examples).

+

The parameter definition x:required for method foo is equivalent +to x without any parameter options (see e.g. previous example), +since positional parameters are per default required. The invocation +in line 21 of Listing 36 will lead to an +undefined variable y in method foo, because no value us passed to +the optional parameter. Note that only trailing positional parameters might be +optional. If we would call method foo of Listing 35 with only one argument, the system would raise an +exception.

+

Similarly, we define method bar in Listing 36 with one required and one optional non-positional +parameter. The parameter definition -y:optional is equivalent to +-y, since non-positional parameter are per default optional. +However, the non-positional parameter -x:required is required. If we +invoke bar without it, the system will raise an exception.

+
+
+

3.7.3. Default Values for Parameters

+

Optional parameters might have a default value. This default value is used, +when no argument is provided for the corresponding parameter. Default values can be +specified for positional and non-positional parameters.

+
Listing 37: Method Parameters with Default Values

+
+
+
nx::Object create o3 {
+
+  #
+  # Positional parameter with default value:
+  #
+  :public object method foo {{x 1} {y 2}} {
+    puts "x=$x y=$y"
+  }
+
+  #
+  # Non-positional parameter with default value:
+  #
+  :public object method bar {{-x 10} {-y 20}} {
+    puts "x=$x y=$y"
+  }
+}
+
+# use default values
+o3 foo
+o3 bar
+

In order to define a default value for a parameter, 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 +Listing 37.

+
+
+

3.7.4. Value Constraints

+

NX provides value constraints for all kind of parameters. By +specifying value constraints a developer can restrict the permissible +values for a parameter and document the expected values in the source +code. Value checking in NX is conditional, it can be turned on or off +in general or on a per-usage level (more about this later). The same +mechanisms can be used not only for input value checking, but as well +for return value checking (we will address this point as well later).

+
+
Built-in Value Constraints
+

NX comes with a set of built-in value constraints, which can be +extended on the scripting level. The built-in checkers are either the +native checkers provided directly by the Next Scripting Framework (the +most efficient checkers) or the value checkers provided by Tcl through +string is …. The built-in checkers have as well the advantage that +they can be used also at any time during bootstrap of an object +system, at a time, when e.g. no objects or methods are defined. The +same checkers are used as well for all C-implemented primitives of NX +and the Next Scripting Framework.

+
+
+value-checkers.png +
+
Figure 38. General Applicable Value Checkers in NX
+
+

+

Figure 38 shows the built-in +general applicable value checkers available in NX, which can be used +for all method and configure 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.

+
Listing 39: Method Parameters with Value Constraints

+
+
+
nx::Object create o4 {
+
+  #
+  # Positional parameter with value constraints:
+  #
+  :public object method foo {x:integer o:object,optional} {
+    puts "x=$x o? [info exists o]"
+  }
+
+  #
+  # Non-positional parameter with value constraints:
+  #
+  :public object method bar {{-x:integer 10} {-verbose:boolean false}} {
+    puts "x=$x verbose=$verbose"
+  }
+}
+
+# The following invocation raises an exception, since the
+# value "a" for parameter "x" is not an integer
+o4 foo a
+

Value constraints are specified as parameter options in the parameter +specifications. The parameter specification x:integer defines x as +a required positional parameter which value is constraint to an +integer. The parameter specification o:object,optional shows how to +combine multiple parameter options. The parameter o is an optional +positional parameter, its value must be an object (see +Listing 39). Value constraints are +specified exactly the same way for non-positional parameters (see +method bar in Listing 39).

+
Listing 40: Parameterized Value Constraints

+
+
+
#
+# Create classes for Person and Project
+#
+nx::Class create Person
+nx::Class create Project
+
+nx::Object create o5 {
+  #
+  # Parameterized value constraints
+  #
+  :public object method work {
+     -person:object,type=Person
+     -project:object,type=Project
+   } {
+    # ...
+  }
+}
+
+#
+# Create a Person and a Project instance
+#
+Person create gustaf
+Project create nx
+
+#
+# Use method with value constraints
+#
+o5 work -person gustaf -project nx
+

The native checkers object, class, metaclass and baseclass can +be further specialized with the parameter option type to restrict +the permissible values to instances of certain classes. We can use for +example the native value constraint object either for testing +whether an argument is some object (without further constraints, as in +Listing 37, method foo), or we can +constrain the value further to some type (direct or indirect instance +of a class). This is shown by method work in +Listing 40 which requires +the parameter -person to be an instance of class Person and the +parameter -project to be an instance of class Project.

+
+
+
Scripted Value Constraints
+

The set of predefined value checkers can be extended by application +programs via defining methods following certain conventions. The user +defined value checkers are defined as methods of the class nx::Slot +or of one of its subclasses or instances. We will address such cases +in the next sections. In the following example we define two new +value checkers on class nx::Slot. The first value checker is called +groupsize, the second one is called choice.

+
Listing 41: Scripted Value Checker for Method Parameters

+
+
+
#
+# Value checker named "groupsize"
+#
+::nx::Slot method type=groupsize {name value} {
+  if {$value < 1 || $value > 6} {
+    error "Value '$value' of parameter $name is not between 1 and 6"
+  }
+}
+
+#
+# Value checker named "choice" with extra argument
+#
+::nx::Slot method type=choice {name value arg} {
+  if {$value ni [split $arg |]} {
+    error "Value '$value' of parameter $name not in permissible values $arg"
+  }
+}
+
+#
+# Create an application class D
+# using the new value checkers
+#
+nx::Class create D {
+  :public method foo {a:groupsize} {
+    # ...
+  }
+  :public method bar {a:choice,arg=red|yellow|green b:choice,arg=good|bad} {
+    # ...
+  }
+}
+
+D create d1
+
+# testing "groupsize";
+# the second call (with value 10) will raise an exception:
+d1 foo 2
+d1 foo 10
+
+# testing "choice"
+# the second call (with value pink for parameter a)
+# will raise an exception:
+d1 bar green good
+d1 bar pink bad
+

In order to define a checker groupsize a method of the name +type=groupsize is defined. This method receives two arguments, +name and value. The first argument is the name of the parameter +(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 Listing 41).

+

The checker groupsize 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 choice +can be used for restricting the values to a set of predefined +constants. This set is defined in the parameter specification. The +parameter a of method bar in Listing 41 +is restricted to the values red, yellow or green, and the +parameter b is restricted to good or bad. Note that the syntax +of the permissible values is solely defined by the definition of the +value checker in lines 13 to 17. The invocation in line 39 will be ok, +the invocation in line 40 will raise an exception, since pink is not +allowed.

+

If the same checks are used in many places in the program, +defining names for the value checker will be the better choice since +it improves maintainability. For seldom used kind of checks, the +parameterized value checkers might be more convenient.

+
+
+
+

3.7.5. Multiplicity

+
+
+

Multiplicity is used to define whether a parameter should receive +single or multiple values.

+
+

A multiplicity specification has a lower and an upper bound. A lower +bound of 0 means that the value might be empty. A lower bound of 1 +means that the parameter needs at least one value. The upper bound +might be 1 or n (or synonymously *). While the upper bound of +1 states that at most one value has to be passed, the upper bound of +n says that multiple values are permitted. Other kinds of +multiplicity are currently not allowed.

+

The multiplicity is written as parameter option in the parameter +specification in the form lower-bound..upper-bound. If no +multiplicity is defined the default multiplicity is 1..1, which +means: provide exactly one (atomic) value (this was the case in the +previous examples).

+
Listing 42: Method Parameters with Explicit Multiplicity

+
+
+
nx::Object create o6 {
+
+  #
+  # Positional parameter with an possibly empty
+  # single value
+  #
+  :public object method foo {x:integer,0..1} {
+    puts "x=$x"
+  }
+
+  #
+  # Positional parameter with an possibly empty
+  # list of values value
+  #
+  :public object method bar {x:integer,0..n} {
+    puts "x=$x"
+  }
+
+  #
+  # Positional parameter with a non-empty
+  # list of values
+  #
+  :public object method baz {x:integer,1..n} {
+    puts "x=$x"
+  }
+}
+

Listing 42 contains three examples for +positional parameters with different multiplicities. Multiplicity is +often combined with value constraints. A parameter specification of +the form x:integer,0..n means that the parameter x receives a list +of integers, which might be empty. Note that the value constraints are +applied to every single element of the list.

+

The parameter specification x:integer,0..1 means that x might be +an integer or it might be empty. This is one style of specifying that +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.

+

All the examples in Listing 42 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, +etc.

+
+
+

3.7.6. Defaults substitution

+

Optional object and method parameters can set a default value. Recall +that default values can be specified for positional and non-positional +parameters, alike. This default value is used to define a +corresponding method-local and object variable, respectively, and to +set it to the default value. By default, the default value is taken +literally (without any substitutions). Default values can also be +preprocessed into a final value using Tcl substitution as provided by +the Tcl [subst] command. To control the kind of substitutions to be +performed, the parameter option substdefault can be provided.

+
Listing 43: Default-value substitution using substdefault

+
+
+
nx::Class create ::D
+nx::Class create ::C {
+  #
+  # By default all substitutions (command, variable, control
+  # characters) are active, when "substdefault" is used:
+  #
+  :property {d:object,type=::D,substdefault {[::D new]}}
+
+  #
+  # The actual property values are computed and
+  # set at instantiation time.
+  #
+  :create ::c
+}
+
+::c cget -d
+

Listing 43 uses substdefault +to provide a default value for the property d. In this example, the +default value is a fresh instance of +class ::D. When the parameter option substdefault is used +default, all substitution kinds of Tcl are active: command, variable, and +backslash substitution. substdefault can be +parametrized to include or to exclude any combination of substitution +kinds by providing a bitmask:

+
    +
  • +

    +substdefault=0b111: all substitutions active (default) +

    +
  • +
  • +

    +substdefault=0b100: substitute backslashes only (like subst -novariables -nocommands) +

    +
  • +
  • +

    +substdefault=0b010: substitute variables only (like subst -nobackslashes -nocommands) +

    +
  • +
  • +

    +substdefault=0b001: substitute commands only (like subst -nobackslashes -novariables) +

    +
  • +
  • +

    +substdefault=0b000: substitute nothing (like subst -nobackslashes -nocommands -novariables, noop) +

    +
  • +
+
+
+
+
+
+

4. Advanced Language Features

+
+

+
+

4.1. Objects, Classes and Meta-Classes

+

+
+
+

4.2. Resolution Order and Next-Path

+

+
+
+

4.3. Details on Method and Configure Parameters

+

The parameter specifications are used in NX for the following +purposes. They are used for

+
    +
  • +

    +the specification of input arguments of methods and commands, for +

    +
  • +
  • +

    +the specification of return values of methods and commands, and for +

    +
  • +
  • +

    +the specification for the initialization of objects. +

    +
  • +
+

We refer to the first two as method parameters and the last one as +configure parameters. The examples in the previous sections all parameter +specification were specifications of method parameters.

+
+
+

Method parameters specify properties about permissible values passed +to methods.

+
+

The method parameter specify how methods are invoked, how the +actual arguments are passed to local variables of the invoked method +and what kind of checks should be performed on these.

+
+
+

Configure parameters are parameters that specify, how objects +can be parameterized upon creation.

+
+

Syntactically, configure parameters and method parameters are the same, +although there are certain differences (e.g. some parameter options +are only applicable for objects parameters, the list of object +parameters is computed dynamically from the class structures, object +parameters are often used in combination with special setter methods, +etc.). Consider the following example, where we define the two +application classes Person and Student with a few properties.

+
Listing 44: Configure Parameters

+
+
+
#
+# Define a class Person with properties "name"
+# and "birthday"
+#
+nx::Class create Person {
+  :property name:required
+  :property birthday
+}
+
+#
+# Define a class Student as specialization of Person
+# with and additional property
+#
+nx::Class create Student -superclass Person {
+  :property matnr:required
+  :property {oncampus:boolean true}
+}
+
+#
+# Create instances using configure parameters
+# for the initialization
+#
+Person create p1 -name Bob
+Student create s1 -name Susan -matnr 4711
+
+# Access property value via "cget" method
+puts "The name of s1 is [s1 cget -name]"
+

The class Person has two properties name and birthday, where the +property name is required, the property birthday is not. The +class Student is a subclass of Person with the additional required +property matnr and an optional property oncampus with the +default value true (see Listing 44). The class diagram below visualizes these +definitions.

+
+
+configure-parameter.png +
+
Figure 45. System and Application Classes
+
+

+

In NX, these definitions imply that instances of the class of Person +have the properties name and birthday as non-positional object +parameters. Furthermore it implies that instances of Student will +have the configure parameters of Person augmented with the object +parameters from Student (namely matnr and oncampus). Based on +these configure parameters, we can create a Person named Bob and a +Student named Susan with the matriculation number 4711 (see line +23 and 24 in <<xmp-object-parameters, +instance variables name, matnr and oncampus (the latter is +initialized with the default value).

+
+

4.3.1. Configure Parameters available for all NX Objects

+

The configure parameters are not limited to the application defined +properties, also NX provides some predefined definitions. Since +Person is a subclass of nx::Object also the configure parameters of +nx::Object are inherited. In the introductory stack example, we used +-mixins applied to an object to denote per-object mixins (see +Listing 8). Since mixins +is defined as a parameter on nx::Object it can be used as an object +parameter -mixins for all objects in NX. To put it in other words, +every object can be configured to have per-object mixins. If we would +remove this definition, this feature would be removed as well.

+

As shown in the introductory examples, every object can be configured +via a scripted initialization block (the optional scripted block +specified at object creation as last argument; see +Listing 5 or +Listing 12). The +scripted block and its meaning are as well defined by the means of +configure parameters. However, this configure parameter is positional (last +argument) and optional (it can be omitted). The following listing shows +the configure parameters of Person p1 and Student s1.

+
Listing 46: Computed Actual Configure Parameter

+
+
+
Configure parameters for Person p1:
+   Command:
+      p1 info lookup syntax configure
+   Result:
+      -name /value/ ?-birthday /value/? ?-object-mixins /mixinreg .../?
+      ?-class /class/? ?-object-filters /filterreg .../? ?/__initblock/?
+
+Configure parameter for Student s1:
+   Command:
+      s1 info lookup syntax configure
+   Result:
+      ?-oncampus /boolean/? -matnr /value/ -name /value/
+      ?-birthday /value/? ?-object-mixins /mixinreg .../? ?-class /class/?
+      ?-object-filters /filterreg .../? ?/__initblock/?
+

The given parameter show, how (a) objects can be configured +at runtime or (b) how new instances can be configured +at creation time via the new or create methods. +Introspection can be used to obtain the configuration +parameters from an object via +p1 info lookup parameters configure +(returning the configure parameters currently applicable for +configure or cget) or from a class +Person info lookup parameters create on a class +(returning the configure parameters applicable when an object +of this class is created)

+

The listed configure parameter types mixinreg and +filterreg are for converting definitions of filters and mixins. The +last value __initblock says that the content of this variable +will be executed in the context of the object being created (before +the constructor init is called). More about the configure parameter +types later.

+
+
+

4.3.2. Configure Parameters available for all NX Classes

+

Since classes are certain kind of objects, classes are parameterized +in the same way as objects. A typical parameter for a class definition +is the relation of the class to its superclass.In our example, we have +specified, that Student has Person as superclass via the +non-positional configure parameter -superclass. If no superclass is +specified for a class, the default superclass is +nx::Object. Therefore nx::Object is the default value for the +parameter superclass.

+

Another frequently used parameter for classes is -mixins to denote +per-class mixins (see e.g. the introductory Stack example in +Listing 10), which is defined in +the same way.

+

Since Student is an instance of the meta-class nx::Class it +inherits the configure parameters from nx::Class (see class diagram +Figure 45). +Therefore, one can use e.g. -superclass in the definition of classes.

+

Since nx::Class is a subclass of nx::Object, the meta-class +nx::Class inherits the parameter definitions from the most general +class nx::Object. Therefore, every class might as well be configured +with a scripted initialization block the same way as objects can be +configured. We used actually this scripted initialization block in +most examples for defining the methods of the class. The following +listing shows (simplified) the parameters applicable for Class +Student.

+
Listing 47: Parameters for Classes

+
+
+
Configure parameter for class nx::Class
+   Command:
+      nx::Class info lookup syntax configure
+   Result:
+      ?-superclass /class .../? ?-mixins /mixinreg .../?
+      ?-filters /filterreg .../? ?-object-mixins /mixinreg .../?
+      ?-class /class/? ?-object-filters /filterreg .../? ?/__initblock/?
+
+
+

4.3.3. User defined Parameter Types

+

More detailed definition of the configure parameter types comes here.

+
+
+

4.3.4. Slot Classes and Slot Objects

+

In one of the previous sections, we defined scripted (application +defined) checker methods on a class named nx::Slot. In general NX +offers the possibility to define value checkers not only for all +usages of parameters but as well differently for method parameters or +configure parameters

+
+
+slots.png +
+
Figure 48. Slot Classes and Objects
+
+

+
+
+

4.3.5. Attribute Slots

+

Still Missing

+
    +
  • +

    +return value checking +

    +
  • +
  • +

    +switch +

    +
  • +
  • +

    +initcmd … +

    +
  • +
  • +

    +subst rules +

    +
  • +
  • +

    +converter +

    +
  • +
  • +

    +incremental slots +

    +
  • +
+
+
+
+
+
+

5. Miscellaneous

+
+

+
+

5.1. Profiling

+

+
+
+

5.2. Unknown Handlers

+

NX provides two kinds of unknown handlers:

+
    +
  • +

    +Unknown handlers for methods +

    +
  • +
  • +

    +Unknown handlers for objects and classes +

    +
  • +
+
+

5.2.1. Unknown Handlers for Methods

+

Object and classes might be equipped +with a method unknown 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

+
Listing 49: Unknown Method Handler

+
+
+
::nx::Object create o {
+  :object method unknown {called_method args} {
+    puts "Unknown method '$called_method' called"
+  }
+}
+
+# Invoke an unknown method for object o:
+o foo 1 2 3
+
+# Output will be: "Unknown method 'foo' called"
+

Without any provision of an unknown method handler, an error will be +raised, when an unknown method is called.

+
+
+

5.2.2. Unknown Handlers for Objects and Classes

+

The next scripting framework provides in addition to unknown method +handlers also a means to dynamically create objects and classes, when +these are referenced. This happens e.g. when superclasses, mixins, or +parent objects are referenced. This mechanism can be used to implement +e.g. lazy loading of these classes. Nsf allows one to register multiple +unknown handlers, each identified by a key (a unique name, different +from the keys of other unknown handlers).

+
Listing 50: Unknown Class Handler

+
+
+
::nx::Class public object method __unknown {name} {
+  # A very simple unknown handler, showing just how
+  # the mechanism works.
+  puts "***** __unknown called with <$name>"
+  ::nx::Class create $name
+}
+
+# Register an unknown handler as a method of ::nx::Class
+::nsf::object::unknown::add nx {::nx::Class __unknown}
+
+::nx::Object create o {
+  # The class M is unknown at this point
+
+  :object mixins add M
+  # The line above has triggered the unknown class handler,
+  # class M is now defined
+
+  puts [:info object mixins]
+  # The output will be:
+  #     ***** __unknown called with <::M>
+  #     ::M
+}
+

The Next Scripting Framework allows one to add, query, delete and list unknown handlers.

+
Listing 51: Unknown Handler registration

+
+
+
# Interface for unknown handlers:
+# nsf::object::unknown::add /key/ /handler/
+# nsf::object::unknown::get /key/
+# nsf::object::unknown::delete /key/
+# nsf::object::unknown::keys
+
References
    +
  • +

    + U. Zdun, M. Strembeck, G. Neumann: + Object-Based and Class-Based Composition of Transitive Mixins, + Information and Software Technology, 49(8) 2007 . +

    +
  • +
  • +

    + G. Neumann and U. Zdun: Filters as a + language support for design patterns in object-oriented scripting + languages. In Proceedings of COOTS’99, 5th Conference on + Object-Oriented Technologies and Systems, San Diego, May 1999. +

    +
  • +
  • +

    + G. Neumann and U. Zdun: Implementing + object-specific design patterns using per-object mixins. In Proc. of + NOSA`99, Second Nordic Workshop on Software Architecture, Ronneby, + Sweden, August 1999. +

    +
  • +
  • +

    + G. Neumann and U. Zdun: Enhancing + object-based system composition through per-object mixins. In + Proceedings of Asia-Pacific Software Engineering Conference (APSEC), + Takamatsu, Japan, December 1999. +

    +
  • +
  • +

    + G. Neumann and U. Zdun: XOTCL, an + object-oriented scripting language. In Proceedings of Tcl2k: The + 7th USENIX Tcl/Tk Conference, Austin, Texas, February 2000. +

    +
  • +
  • +

    + G. Neumann and U. Zdun: Towards the Usage + of Dynamic Object Aggregations as a Form of Composition In: + Proceedings of Symposium of Applied Computing (SAC’00), Como, + Italy, Mar 19-21, 2000. +

    +
  • +
  • +

    + G. Neumann, S. Sobernig: XOTcl 2.0 - A + Ten-Year Retrospective and Outlook, in: Proceedings of the Sixteenth + Annual Tcl/Tk Conference, Portland, Oregon, October, 2009. +

    +
  • +
  • +

    + J. K. Ousterhout: Tcl: An embeddable command + language. In Proc. of the 1990 Winter USENIX Conference, January 1990. +

    +
  • +
  • +

    + J. K. Ousterhout: Scripting: Higher Level + Programming for the 21st Century, IEEE Computer 31(3), March 1998. +

    +
  • +
  • +

    + D. Wetherall and C. J. Lindblad: Extending Tcl for + Dynamic Object-Oriented Programming. Proc. of the Tcl/Tk Workshop '95, + July 1995. +

    +
  • +
+
+
+
+
+
+

+ + + Index: library/xotcl/apps/comm/link-checker.xotcl =================================================================== diff -u -r9a0b8bb0992be0561d8187c275fc1d9b7e0bbcd0 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- library/xotcl/apps/comm/link-checker.xotcl (.../link-checker.xotcl) (revision 9a0b8bb0992be0561d8187c275fc1d9b7e0bbcd0) +++ library/xotcl/apps/comm/link-checker.xotcl (.../link-checker.xotcl) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -15,7 +15,7 @@ -local A string match pattern to decide which url should be treated as local e.g. -local *wu-wien.ac.at/* - Per default the locality filter ist set + Per default the locality filter is set to the name of the host followed by '/*' -restrict 0 or 1, sets the locality filter to the subtree implied by the URL Index: library/xotcl/doc/Announce-1.6.0 =================================================================== diff -u -rb5c493afe905b1bafc17697ed3ce01d1662c77b3 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- library/xotcl/doc/Announce-1.6.0 (.../Announce-1.6.0) (revision b5c493afe905b1bafc17697ed3ce01d1662c77b3) +++ library/xotcl/doc/Announce-1.6.0 (.../Announce-1.6.0) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -58,7 +58,7 @@ will be marked as deprecated in the near future. Please note that the behavior of the match pattern has - changed and is therefor not completely compatible with + changed and is therefore not completely compatible with prior versions. * New info subcommands: Index: library/xotcl/doc/tutorial.html =================================================================== diff -u -rcfb3421c9ebcc80ee2b48544717135b56c7c9946 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- library/xotcl/doc/tutorial.html (.../tutorial.html) (revision cfb3421c9ebcc80ee2b48544717135b56c7c9946) +++ library/xotcl/doc/tutorial.html (.../tutorial.html) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -861,7 +861,7 @@

Initially XOTcl offers two new commands: Object and Class. They represent hooks to the features of the language. This section discusses both of them in detail and shows how they -function in the context of XOTcl. Note, that even if most of this is +function in the context of XOTcl. Note that even if most of this is compatible to OTcl, a few changes occur. For this reason, this section is no introduction to plain OTcl. The Object command provides access to the Object class, which holds the common @@ -1024,7 +1024,7 @@

  • self class: the self command with the argument class returns the name of the - class, which holds the currently executing instproc. Note, that this + class, which holds the currently executing instproc. Note that this may be different to the class of the current object. If it is called from a proc it returns an empty string.

    @@ -1041,7 +1041,7 @@ my set persons($name) [clock seconds] }

    -

    Note, that there is a difference to the realization of these +

    Note that there is a difference to the realization of these object information to OTcl. XOTcl uses commands in order to make XOTcl-methods compatible to Tcl-procedures and accessible via namespace-paths. OTcl uses the three variables self, class @@ -1544,8 +1544,8 @@ leaves it's instances with the class Object.

    So all empty class- and superclass-relationships are automatically -reset to Object. Note, that this are differences to OTcl, -where the destruction of an class destroys all instances and an empty +reset to Object. Note that this are differences to OTcl, +where the destruction of a class destroys all instances and an empty super-class list remains empty.

    Method Chaining @@ -1622,7 +1622,7 @@ four instance variables cookName, roomNumber, doorPosition and stoveType set up with default values in this order (since this is the order of the classes in the -next-path). Note, that the order is important, because one missing +next-path). Note that the order is important, because one missing next call, in one of the init methods, means that succeeding init methods will not be executed. This mechanism functions equally on all kinds of instprocs, not only on constructors. @@ -1754,8 +1754,7 @@ predefined meta-class Class, or by adding an instmixin class (see below) containing Class to the precedence chain of the class. By defining Object -instmixin Class one can even change the object system of XOTcl in -in a way such that every created Object is a meta-class. +instmixin Class one can even change the object system of XOTclin a way such that every created Object is a meta-class.

    Since the concept of a meta-class are sometimes confusing to people of a background of some other programming @@ -1970,7 +1969,7 @@ doInitializations.

    - Note, that recreate is not called, when a someone tries + Note that recreate is not called, when a someone tries to recreate a class as an object or an object as a class. In these cases, destroy + create are used.

    @@ -2320,7 +2319,7 @@
     

    All messages to a filtered object must go through the filter before they reach their destination object. A simple example would be a sole filter on the class of the object. To define such a filter two steps -are necessary. Firstly an filter method has to be defined, then the +are necessary. Firstly a filter method has to be defined, then the filter has to be registered. The filter method consists of three parts which are all optional. A filter method has the following form:

    @@ -2812,13 +2811,13 @@

    The inverse operation of info mixin is mixinof finds -out, into which objects an per-object mixin class is mixed into. +out, into which objects a per-object mixin class is mixed into.
       clsName info mixinof ?pattern?
     
    -

    Note, that the constructors (init methods) of per-object mixins (and per-class mixins) +

    Note that the constructors (init methods) of per-object mixins (and per-class mixins) are only called, if the mixin is registered already during object initialization (when init is called). For per-object mixins, one can achieve the initialization of a mixin via an idiom like @@ -2827,7 +2826,7 @@

    that registers the mixin before init is called. When a mixin is registered after object creation and it needs initializations, it is necessary to -define special methods for this. Note, that the behavior described +define special methods for this. Note that the behavior described here is introduced in version 0.84 to ensure consistent behavior of intrinsic classes, per-object and per-class mixins, and to achieve predictable behavior for dynamic registration for all kind of mixins, @@ -2897,7 +2896,7 @@ className instmixin mixinList The inverse operation of info inmixin is instmixinof finds -out, into which objects an per-object mixin class is mixed into. +out, into which objects a per-object mixin class is mixed into.
       className info instmixinof ?-closure? ?pattern?
    @@ -2962,7 +2961,7 @@
     

    Per-class mixins are applied transitively. That means the per-class -mixin A of a per-class mixin B is also applied for an object in in B's +mixin A of a per-class mixin B is also applied for an objectin B's scope. This is exactly the same as how superclasses are applied for instances. Consider the following example

    @@ -3244,7 +3243,7 @@

    -Note, that the list of possible actions can be +Note that the list of possible actions can be extended by extending the class ::xotcl::Relations.

    @@ -3257,9 +3256,9 @@ accessible within their scope. But the interceptors are mechanisms, which cover more then their sole scope. The meaningful usage of the meta-programming abilities often requires to go further and to get -information from the caller's and the callee's scope (e.g for +information from the caller's and the callee's scope (e.g. for delegation decisions). Therefore, we introduced rich call-stack -information for the interceptors. Note, that these are also available +information for the interceptors. Note that these are also available for ordinary methods, but the "called..." info options return empty strings.

    @@ -3383,7 +3382,7 @@


    -

    Note, that three options with the prefix calling +

    Note that three options with the prefix calling represent the values of self, self proc, and self class in the scope where the original call was invoked. In the following section we will show a simple program in which all of the @@ -4770,7 +4769,7 @@

    Automatic Name Creation

    The XOTcl autoname -instance method provides an simple way to take the task of +instance method provides a simple way to take the task of automatically creating names out of the responsibility of the programmer. The example below shows how to create on each invocation of method new an agent with a fresh name Index: library/xotcl/library/comm/Httpd.xotcl =================================================================== diff -u -r6b093438fe4e4b2aae05f6662de2346980a0a111 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- library/xotcl/library/comm/Httpd.xotcl (.../Httpd.xotcl) (revision 6b093438fe4e4b2aae05f6662de2346980a0a111) +++ library/xotcl/library/comm/Httpd.xotcl (.../Httpd.xotcl) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -612,7 +612,7 @@ Httpd::Responder::Wrk instproc respond {} { my instvar fileName method resourceName hasFormData [my info parent] instvar respondpatterns - ### auch das ist ein kandidat fuer eine chain of responsibility + ### auch das ist ein Kandidat fuer eine Chain-of responsibility foreach {pattern action} $respondpatterns { if {[regexp $pattern "$method $resourceName $hasFormData"]} { my $action @@ -752,7 +752,7 @@ # (credentials) ok sind. Hier habe ich probleme auf die sachen, # die der worker gesendet (bspw. nonce) hat zu kommen. Ich # weiß, man kann mit [my info children] daran kommen. Aber, - # was ist, wenn man mehrere Worker hat? + # was is, wenn man mehrere Worker hat? ## Fredj, das sollte kein Problem sein: das credentialsNotOk wird ## vom aktuellen worker (respond) aufgerufen. man kann dem *NotOk Index: library/xotcl/library/lib/trace.xotcl =================================================================== diff -u -r073177c8b1304443107efeeb0c334e9477346778 -r2352fb1a509bd00ec49c9677798caad6bfec4d71 --- library/xotcl/library/lib/trace.xotcl (.../trace.xotcl) (revision 073177c8b1304443107efeeb0c334e9477346778) +++ library/xotcl/library/lib/trace.xotcl (.../trace.xotcl) (revision 2352fb1a509bd00ec49c9677798caad6bfec4d71) @@ -46,7 +46,7 @@ @ Object instproc statFilter {} { Description {Experimental statistics filter} } - @ Object instproc showVars {args "ist of variables"} { + @ Object instproc showVars {args "list of variables"} { Description {Show the values of the specified variables (or of all variables) of an object on stderr.} }