Provided by: tcl9.0-doc_9.0.1+dfsg-1_all bug

NAME

       oo::define, oo::objdefine, oo::Slot - define and configure classes and objects

SYNOPSIS

       package require tcl::oo

       oo::define class defScript
       oo::define class subcommand arg ?arg ...?
       oo::objdefine object defScript
       oo::objdefine object subcommand arg ?arg ...?

       oo::Slot arg...

CLASS HIERARCHY

       oo::objectoo::Slot
________________________________________________________________________________________________________________

DESCRIPTION

       The  oo::define command is used to control the configuration of classes, and the oo::objdefine command is
       used to control  the  configuration  of  objects  (including  classes  as  instance  objects),  with  the
       configuration being applied to the entity named in the class or the object argument.  Configuring a class
       also  updates the configuration of all subclasses of the class and all objects that are instances of that
       class or which mix it in  (as  modified  by  any  per-instance  configuration).  The  way  in  which  the
       configuration  is  done is controlled by either the defScript argument or by the subcommand and following
       arg arguments; when the second is present, it is exactly as if all the arguments from subcommand  onwards
       are made into a list and that list is used as the defScript argument.

       Note  that the constructor for oo::class will call oo::define on the script argument that it is provided.
       This is a convenient way to create and define a class in one step.

CONFIGURING CLASSES

       The following commands are supported in the defScript for oo::define, each of which may also be  used  in
       the subcommand form:

       classmethod name ?argList bodyScrip?
              This  creates  a  class  method,  or  (if argList and bodyScript are omitted) promotes an existing 2
              method on the class object to be a class method. The name, argList and bodyScript arguments are as 2
              in the method definition, below.                                                                   2

              Class methods can be called on either the class itself or on the instances  of  that  class.  When 2
              they  are  called, the current object (see the sel and my commands) is the class on which they are 2
              called or the class of the instance on which they are called, depending on whether they are called 2
              on the class or an instance of the class, respectively. If called on a subclass or instance of the 2
              subclass, the current object is the subclass.                                                      2

              In a private definition context, the methods as invoked  on  classes  are  not  private,  but  the 2
              methods as invoked on instances of classes are private.                                            2

       constructor argList bodyScript
              This  creates  or  updates  the  constructor  for a class. The formal arguments to the constructor
              (defined using the same format as for the Tcl proc command) will be argList, and the body  of  the
              constructor  will  be  bodyScript.  When  the  body  of  the constructor is evaluated, the current
              namespace of the constructor will be a namespace that is unique to the object  being  constructed.
              Within the constructor, the next command should be used to call the superclasses' constructors. If
              bodyScript is the empty string, the constructor will be deleted.

              Classes  do  not  need  to  have  a  constructor  defined.  If none is specified, the superclass's
              constructor will be used instead.

       destructor bodyScript
              This creates or updates the destructor for a class. Destructors take no arguments, and the body of
              the destructor will be bodyScript. The destructor is called when objects of the class are deleted,
              and when called will have the object's unique namespace  as  the  current  namespace.  Destructors
              should  use  the next command to call the superclasses' destructors. Note that destructors are not
              called in all situations (e.g. if the interpreter  is  destroyed).  If  bodyScript  is  the  empty
              string, the destructor will be deleted.
              Note  that  errors  during the evaluation of a destructor are not returned to the code that causes
              the destruction of an object. Instead, they are passed to the currently-defined bgerror handler.

       export name ?name ...?
              This arranges for each of the named methods, name, to be exported (i.e. usable outside an instance
              through the instance object's  command)  by  the  class  being  defined.  Note  that  the  methods
              themselves  may  be  actually  defined  by  a  superclass;  subclass  exports  override superclass
              visibility, and may in turn be overridden by instances.

       forward name cmdName ?arg ...?
              This creates or updates a forwarded method called name. The method is defined be forwarded to  the
              command  called  cmdName,  with  additional  arguments,  arg  etc.,  added  before those arguments
              specified by the caller of the method. The cmdName will always be resolved using the rules of  the
              invoking  objects'  namespaces,  i.e.,  when  cmdName  is not fully-qualified, the command will be
              searched for in each object's namespace, using the instances' namespace's path, or by  looking  in
              the  global  namespace.   The method will be exported if name starts with a lower-case letter, and
              non-exported otherwise.

              If in a private definition context (see the  private  definition  command,  below),  this  command 2
              creates private forwarded methods.

       initialise script

       initialize script
              This  evaluates script in a context which supports local variables and where the current namespace 2
              is the instance namespace of the class object itself. This is useful for setting up, e.g.,  class- 2
              scoped variables.

       method name ?option? argList bodyScript
              This  creates  or updates a method that is implemented as a procedure-like script. The name of the
              method is name, the formal arguments to the method (defined using the same format as for  the  Tcl
              proc command) will be argList, and the body of the method will be bodyScript. When the body of the
              method is evaluated, the current namespace of the method will be a namespace that is unique to the
              current  object.  The  method  will  be exported if name starts with a lower-case letter, and non-
              exported otherwise; this behavior can be overridden via  export  and  unexport  or  by  specifying 2
              -export, -private or -unexport in the optional parameter option.

              If  in a private definition context (see the private definition command, below) or if the -private 2
              flag is given for option, this command creates private procedure-like methods.

       private cmd arg...

       private script
              This evaluates the script (or the list of command and arguments  given  by  cmd  and  args)  in  a 2
              context where the definitions made on the current class will be private definitions.               2

              The  following  class  definition  commands  are  affected  by private: forward, method, self, and 2
              variable. Nesting private inside private  has  no  cumulative  effect;  the  innermost  definition 2
              context  is just a private definition context. All other definition commands have no difference in 2
              behavior when used in a private definition context.                                                2

       self subcommand arg ...

       self script

       self   This command is equivalent to calling oo::objdefine on the class being  defined  (see  CONFIGURING
              OBJECTS  below  for  a  description  of  the  supported values of subcommand). It follows the same
              general pattern of argument handling as the oo::define and oo::objdefine commands, and “oo::define
              cls self subcommand ...”  operates identically to “oo::objdefine cls subcommand ...”.

              If no arguments at all are used, this gives the name of the class currently being configured.   If 2
              in  a  private  definition context (see the private definition command, below), the definitions on 2
              the class object will also be made in a private definition context.

       superclass ?-slotOperation? ?className ...?
              This slot (see SLOTTED DEFINITIONS below) allows the alteration of the superclasses of  the  class
              being  defined.  Each className argument names one class that is to be a superclass of the defined
              class. Note that objects must not be changed from being classes  to  being  non-classes  or  vice-
              versa,  that  an  empty  parent  class is equivalent to oo::object, and that the parent classes of
              oo::object and oo::class may not be modified.  By default, this slot works by replacement.

       unexport name ?name ...?
              This arranges for each of the named methods, name, to be not exported (i.e. not usable outside the
              instance through the instance object's command, but instead just through the my command visible in
              each object's context) by the class being  defined.  Note  that  the  methods  themselves  may  be
              actually  defined  by  a superclass; subclass unexports override superclass visibility, and may be
              overridden by instance unexports.

       variable ?-slotOperation? ?name ...?
              This slot (see SLOTTED DEFINITIONS  below)  arranges  for  each  of  the  named  variables  to  be
              automatically  made  available  in  the  methods, constructor and destructor declared by the class
              being defined. Each variable name must not have any namespace separators and must not look like an
              array access. All variables will be actually present in the namespace of the  instance  object  on
              which  the  method  is executed. Note that the variable lists declared by a superclass or subclass
              are completely disjoint, as are variable lists declared by instances; the list of  variable  names
              is  just  for  methods (and constructors and destructors) declared by this class. By default, this
              slot works by appending.

              If in a private definition  context  (see  the  private  definition  command,  below),  this  slot 2
              manipulates  the  list of private variable bindings for this class. In a private variable binding, 2
              the name of the variable within the instance  object  is  different  to  the  name  given  in  the 2
              definition; the name used in the definition is the name that you use to access the variable within 2
              the  methods  of  this  class, and the name of the variable in the instance namespace has a unique 2
              prefix that makes accidental use from other classes extremely unlikely.

   ADVANCED CLASS CONFIGURATION OPTIONS
       The following definitions are also supported, but are not required in simple programs:

       definitionnamespace ?kind? namespaceName
              This allows control over what namespace will be used by the oo::define and oo::objdefine  commands 2
              to look up the definition commands they use. When any object has a definition operation applied to 2
              it,  the  class  that it is an instance of (and its superclasses and mixins) is consulted for what 2
              definition namespace to use. oo::define gets the class definition namespace,  and  ::oo::objdefine 2
              gets the instance definition namespace, but both otherwise use the identical lookup operation.     2

              This  sets  the  definition namespace of kind kind provided by the current class to namespaceName. 2
              The namespaceName must refer to a currently existing namespace, or must be the  empty  string  (to 2
              stop  the  current  class  from having such a namespace connected). The kind, if supplied, must be 2
              either -class (the default) or -instance to  specify  the  whether  the  namespace  for  use  with 2
              oo::define or oo::objdefine respectively is being set.                                             2

              The class oo::object has its instance namespace locked to ::oo::objdefine, and the class oo::class 2
              has  its  class  namespace  locked to ::oo::define. A consequence of this is that effective use of 2
              this feature for classes requires the definition of a metaclass.                                   2

       deletemethod name ?name ...?
              This deletes each of the methods called name from  a  class.  The  methods  must  have  previously
              existed  in  that  class.  Does  not  affect the superclasses of the class, nor does it affect the
              subclasses or instances of the class (except when they have a call chain through the  class  being
              modified) or the class object itself.

       filter ?-slotOperation? ?methodName ...?
              This  slot  (see SLOTTED DEFINITIONS below) sets or updates the list of method names that are used
              to guard whether method call to instances of the class may be called and what the method's results
              are. Each methodName names a single filtering method (which may be exposed or not exposed); it  is
              not  an  error  for a non-existent method to be named since they may be defined by subclasses.  By
              default, this slot works by appending.

       mixin ?-slotOperation? ?className ...?
              This slot (see SLOTTED DEFINITIONS below) sets or updates the list of additional classes that  are
              to  be  mixed  into  all the instances of the class being defined. Each className argument names a
              single class that is to be mixed in.  By default, this slot works by replacement.

       renamemethod fromName toName
              This renames the method called fromName in a class to toName.  The  method  must  have  previously
              existed  in  the  class,  and toName must not previously refer to a method in that class. Does not
              affect the superclasses of the class, nor does it affect the subclasses or instances of the  class
              (except when they have a call chain through the class being modified), or the class object itself.
              Does not change the export status of the method; if it was exported before, it will be afterwards.

CONFIGURING OBJECTS

       The  following  commands are supported in the defScript for oo::objdefine, each of which may also be used
       in the subcommand form:

       export name ?name ...?
              This arranges for each of the named methods, name, to be exported (i.e. usable outside the  object
              through the object's command) by the object being defined. Note that the methods themselves may be
              actually defined by a class or superclass; object exports override class visibility.

       forward name cmdName ?arg ...?
              This  creates or updates a forwarded object method called name. The method is defined be forwarded
              to the command called cmdName, with additional arguments, arg etc., added before  those  arguments
              specified  by  the  caller  of  the  method.  Forwarded methods should be deleted using the method
              subcommand. The method will be exported if name starts with a lower-case letter, and  non-exported
              otherwise.

              If  in  a  private  definition  context  (see the private definition command, below), this command 2
              creates private forwarded methods.

       method name ?option? argList bodyScript
              This creates, updates or deletes an object method. The name of the  method  is  name,  the  formal
              arguments  to  the  method  (defined  using  the  same format as for the Tcl proc command) will be
              argList, and the body of the method will be bodyScript. When the body of the method is  evaluated,
              the  current  namespace of the method will be a namespace that is unique to the object. The method
              will be exported if name starts with a lower-case letter, and non-exported otherwise; this can  be 2
              overridden  by  specifying -export, -private or -unexport in the optional parameter option, or via 2
              the export and unexport definitions.

              If in a private definition context (see the private definition command, below) or if the  -private 2
              flag is given for option, this command creates private procedure-like methods.

       mixin ?-slotOperation? ?className ...?
              This  slot (see SLOTTED DEFINITIONS below) sets or updates a per-object list of additional classes
              that are to be mixed into the object. Each argument, className, names a single class that is to be
              mixed in.  By default, this slot works by replacement.

       private cmd arg...

       private script
              This evaluates the script (or the list of command and arguments  given  by  cmd  and  args)  in  a 2
              context where the definitions made on the current object will be private definitions.              2

              The  following  class  definition commands are affected by private: forward, method, and variable. 2
              Nesting private inside private has no cumulative effect; the innermost definition context is  just 2
              a  private  definition  context. All other definition commands have no difference in behavior when 2
              used in a private definition context.                                                              2

       unexport name ?name ...?
              This arranges for each of the named methods, name, to be not exported (i.e. not usable outside the
              object through the object's command, but instead just  through  the  my  command  visible  in  the
              object's  context)  by  the object being defined. Note that the methods themselves may be actually
              defined by a class; instance unexports override class visibility.

       variable ?-slotOperation? ?name ...?
              This slot (see SLOTTED DEFINITIONS  below)  arranges  for  each  of  the  named  variables  to  be
              automatically  made  available in the methods declared by the object being defined.  Each variable
              name must not have any namespace separators and must not look like an array access. All  variables
              will be actually present in the namespace of the object on which the method is executed. Note that
              the  variable  lists  declared  by  the  classes and mixins of which the object is an instance are
              completely disjoint; the list of variable names is just for methods declared by  this  object.  By
              default, this slot works by appending.

              If  in  a  private  definition  context  (see  the  private  definition command, below), this slot 2
              manipulates the list of private variable bindings for this object.  In a private variable binding, 2
              the name of the variable within the instance  object  is  different  to  the  name  given  in  the 2
              definition; the name used in the definition is the name that you use to access the variable within 2
              the  methods of this instance object, and the name of the variable in the instance namespace has a 2
              unique prefix that makes accidental use from superclass methods extremely unlikely.

   ADVANCED OBJECT CONFIGURATION OPTIONS
       The following definitions are also supported, but are not required in simple programs:

       class className
              This allows the class  of  an  object  to  be  changed  after  creation.  Note  that  the  class's
              constructors  are  not  called when this is done, and so the object may well be in an inconsistent
              state unless additional configuration work is done.

       deletemethod name ?name ...
              This deletes each of the methods called name from an object.  The  methods  must  have  previously
              existed  in  that  object  (e.g.,  because  it was created through oo::objdefine method). Does not
              affect the classes that the object is an instance of, or  remove  the  exposure  of  those  class-
              provided methods in the instance of that class.

       filter ?-slotOperation? ?methodName ...?
              This  slot  (see SLOTTED DEFINITIONS below) sets or updates the list of method names that are used
              to guard whether a method call to the object may be called and  what  the  method's  results  are.
              Each  methodName  names a single filtering method (which may be exposed or not exposed); it is not
              an error for a non-existent method to be named. Note that the actual list of filters also  depends
              on  the  filters  set  upon  any classes that the object is an instance of.  By default, this slot
              works by appending.

       renamemethod fromName toName
              This renames the method called fromName in an object to toName.  The method must  have  previously
              existed  in  the object, and toName must not previously refer to a method in that object. Does not
              affect the classes that the object is an instance of and cannot rename in an instance  object  the
              methods  provided  by  those  classes  (though  a  oo::objdefine  forwarded  method may provide an
              equivalent capability). Does not change the export status  of  the  method;  if  it  was  exported
              before, it will be afterwards.

       self   This gives the name of the object currently being configured.                                      2

PRIVATE METHODS

       When  a  class  or  instance  has  a  private method, that private method can only be invoked from within 2
       methods of that class or instance. Other callers of the object's methods cannot invoke  private  methods, 2
       it  is  as  if the private methods do not exist. However, a private method of a class can be invoked from 2
       the class's methods when those methods are being used on another instance object; this means that a class 2
       can use them to coordinate behaviour between several instances of itself  without  interfering  with  how 2
       other  classes (especially either subclasses or superclasses) interact. Private methods precede all mixed 2
       in classes in the method call order (as reported by self call).

SLOTTED DEFINITIONS

       Some of the configurable definitions of a class or object are slotted definitions. This  means  that  the
       configuration is implemented by a slot object, that is an instance of the class oo::Slot, which manages a
       list of values (class names, variable names, etc.) that comprises the contents of the slot.

       The oo::Slot class defines six operations (as methods) that may be done on the slot:

       slot -append ?member ...?
              This appends the given member elements to the slot definition.

       slot -appendifnew ?member ...?
              This appends the given member elements to the slot definition if they do not already exist.        2

       slot -clear
              This sets the slot definition to the empty list.

       slot -prepend ?member ...?
              This prepends the given member elements to the slot definition.                                    2

       slot -remove ?member ...?
              This removes the given member elements from the slot definition.                                   2

       slot -set ?member ...?
              This replaces the slot definition with the given member elements.

       A  consequence  of  this  is  that  any use of a slot's default operation where the first member argument
       begins with a hyphen will be an error. One of the above operations should be  used  explicitly  in  those
       circumstances.

       You  only  need  to  make an instance of oo::Slot if you are definining your own slot that behaves like a
       standard slot.

   SLOT IMPLEMENTATION
       Internally, slot objects also define a method --default-operation  which  is  forwarded  to  the  default
       operation of the slot (thus, for the class “variable” slot, this is forwarded to “my -append”), and these
       methods which provide the implementation interface:

       slot Get
              Returns a list that is the current contents of the slot, but does not modify the slot. This method
              must  always  be  called from a stack frame created by a call to oo::define or oo::objdefine. This
              method should not return an error unless it is called from outside a definition  context  or  with
              the wrong number of arguments.

              The elements of the list should be fully resolved, if that is a meaningful concept to the slot.    2

       slot Resolve slotElement
              Returns  slotElement  with a resolution operation applied to it, but does not modify the slot. For 2
              slots of simple strings, this is an operation that does nothing, whereas  for  slots  of  classes, 2
              this  maps a class name to its fully-qualified class name.  This method must always be called from 2
              a stack frame created by a call to oo::define or oo::objdefine.  This method should not return  an 2
              error unless it is called from outside a definition context or with the wrong number of arguments; 2
              unresolvable  arguments should be returned as is (as not all slot operations strictly require that 2
              values are resolvable to work).                                                                    2

              Implementations should not enforce uniqueness and ordering constraints in this method; that is the 2
              responsibility of the Set method.                                                                  2

       slot Resolve element
              This converts an element of the slotted collection into its resolved form; for a simple value,  it 2
              could  just  return  the  value, but for a slot that contains references to commands or classes it 2
              should convert those into their fully-qualified  forms  (so  they  can  be  compared  with  string 2
              equals): that could be done by forwarding to namespace which or similar.

       slot Set elementList
              Sets  the  contents  of the slot to the list elementList and returns the empty string. This method
              must always be called from a stack frame created by a call to oo::define  or  oo::objdefine.  This
              method may return an error if it rejects the change to the slot contents (e.g., because of invalid
              values)  as  well as if it is called from outside a definition context or with the wrong number of
              arguments.

              This method may reorder and filter the elements if this is  necessary  in  order  to  satisfy  the
              underlying constraints of the slot. (For example, slots of classes enforce a uniqueness constraint
              that places each element in the earliest location in the slot that it can.)

       The  implementation of these methods is slot-dependent (and responsible for accessing the correct part of
       the class or object definition). Slots also have an unknown  method  handler  to  tie  all  these  pieces
       together,  and  they hide their destroy method so that it is not invoked inadvertently. It is recommended
       that any user changes to the slot mechanism itself be restricted to defining new operations  whose  names
       start with a hyphen.

       Note  that  slot instances are not expected to contain the storage for the slot they manage; that will be
       in or attached to the class or object  that  they  manage.  Those  instances  should  provide  their  own
       implementations  of  the Get and Set methods (and optionally Resolve; that defaults to a do-nothing pass-
       through).

       Most slot operations will initially Resolve their argument list, combine it with the results of  the  Get 2
       method,  and  then Set the result.  Some operations omit one or both of the first two steps; omitting the 2
       third would result in an idempotent read-only operation (but the  standard  mechanism  for  reading  from 2
       slots is via info class and info object).

EXAMPLES

       This  example  demonstrates how to use both forms of the oo::define and oo::objdefine commands (they work
       in the same way), as well as illustrating four of their subcommands.

              oo::class create c
              c create o
              oo::define c method foo {} {
                  puts "world"
              }
              oo::objdefine o {
                  method bar {} {
                      my Foo "hello "
                      my foo
                  }
                  forward Foo ::puts -nonewline
                  unexport foo
              }
              o bar                 prints "hello world"
              o foo                 error "unknown method foo"
              o Foo Bar             error "unknown method Foo"
              oo::objdefine o renamemethod bar lollipop
              o lollipop            prints "hello world"

       This example shows how additional classes can be mixed into an object. It also shows how mixin is a  slot
       that supports appending:

              oo::object create inst
              inst m1               error "unknown method m1"
              inst m2               error "unknown method m2"

              oo::class create A {
                  method m1 {} {
                      puts "red brick"
                  }
              }
              oo::objdefine inst {
                  mixin A
              }
              inst m1               prints "red brick"
              inst m2               error "unknown method m2"

              oo::class create B {
                  method m2 {} {
                      puts "blue brick"
                  }
              }
              oo::objdefine inst {
                  mixin -append B
              }
              inst m1               prints "red brick"
              inst m2               prints "blue brick"

       This example shows how to create and use class variables. It is a class that counts how many instances of 2
       itself have been made.                                                                                    2

              oo::class create Counted                                                                           2
              oo::define Counted {                                                                               2
                  initialise {                                                                                   2
                      variable count 0                                                                           2
                  }                                                                                              2

                  variable number                                                                                2
                  constructor {} {                                                                               2
                      classvariable count                                                                        2
                      set number [incr count]                                                                    2
                  }                                                                                              2

                  method report {} {                                                                             2
                      classvariable count                                                                        2
                      puts "This is instance $number of $count"                                                  2
                  }                                                                                              2
              }                                                                                                  2

              set a [Counted new]                                                                                2
              set b [Counted new]                                                                                2
              $a report                                                                                          2
                       This is instance 1 of 2                                                                  2
              set c [Counted new]                                                                                2
              $b report                                                                                          2
                       This is instance 2 of 3                                                                  2
              $c report                                                                                          2
                       This is instance 3 of 3                                                                  2

       This  example  demonstrates  how  to  use  class  methods. (Note that the constructor for oo::class calls 2
       oo::define on the class.)                                                                                 2

              oo::class create DBTable {                                                                         2
                  classmethod find {description} {                                                               2
                      puts "DB: locate row from [self] matching $description"                                    2
                      return [my new]                                                                            2
                  }                                                                                              2
                  classmethod insert {description} {                                                             2
                      puts "DB: create row in [self] matching $description"                                      2
                      return [my new]                                                                            2
                  }                                                                                              2
                  method update {description} {                                                                  2
                      puts "DB: update row [self] with $description"                                             2
                  }                                                                                              2
                  method delete {} {                                                                             2
                      puts "DB: delete row [self]"                                                               2
                      my destroy; # Just delete the object, not the DB row                                       2
                  }                                                                                              2
              }                                                                                                  2

              oo::class create Users {                                                                           2
                  superclass DBTable                                                                             2
              }                                                                                                  2
              oo::class create Groups {                                                                          2
                  superclass DBTable                                                                             2
              }                                                                                                  2

              set u1 [Users insert "username=abc"]                                                               2
                       DB: create row from ::Users matching username=abc                                        2
              set u2 [Users insert "username=def"]                                                               2
                       DB: create row from ::Users matching username=def                                        2
              $u2 update "group=NULL"                                                                            2
                       DB: update row ::oo::Obj124 with group=NULL                                              2
              $u1 delete                                                                                         2
                       DB: delete row ::oo::Obj123                                                              2
              set g [Group find "groupname=webadmins"]                                                           2
                       DB: locate row ::Group with groupname=webadmins                                          2
              $g update "emailaddress=admins"                                                                    2
                       DB: update row ::oo::Obj125 with emailaddress=admins                                     2

       This example shows how to make a custom  definition  for  a  class.  Note  that  it  explicitly  includes 2
       delegation to the existing definition commands via namespace path.                                        2

              namespace eval myDefinitions {                                                                     2
                  # Delegate to existing definitions where not overridden                                        2
                  namespace path ::oo::define                                                                    2

                  # A custom type of method                                                                      2
                  proc exprmethod {name arguments body} {                                                        2
                      tailcall method $name $arguments [list expr $body]                                         2
                  }                                                                                              2

                  # A custom way of building a constructor                                                       2
                  proc parameters args {                                                                         2
                      uplevel 1 [list variable {*}$args]                                                         2
                      set body [join [lmap a $args {                                                             2
                          string map [list VAR $a] {                                                             2
                              set [my varname VAR] [expr {double($VAR)}]                                         2
                          }                                                                                      2
                      }] ";"]                                                                                    2
                      tailcall constructor $args $body                                                           2
                  }                                                                                              2
              }                                                                                                  2

              # Bind the namespace into a (very simple) metaclass for use                                        2
              oo::class create exprclass {                                                                       2
                  superclass oo::class                                                                           2
                  definitionnamespace myDefinitions                                                              2
              }                                                                                                  2

              # Use the custom definitions                                                                       2
              exprclass create quadratic {                                                                       2
                  parameters a b c                                                                               2
                  exprmethod evaluate {x} {                                                                      2
                      ($a * $x**2) + ($b * $x) + $c                                                              2
                  }                                                                                              2
              }                                                                                                  2

              # Showing the resulting class and object in action                                                 2
              quadratic create quad 1 2 3                                                                        2
              for {set x 0} {$x <= 4} {incr x} {                                                                 2
                  puts [format "quad(%d) = %.2f" $x [quad evaluate $x]]                                          2
              }                                                                                                  2
                       quad(0) = 3.00                                                                           2
                       quad(1) = 6.00                                                                           2
                       quad(2) = 11.00                                                                          2
                       quad(3) = 18.00                                                                          2
                       quad(4) = 27.00                                                                          2

SEE ALSO

       next(3tcl), oo::class(3tcl), oo::object(3tcl)

KEYWORDS

       class, definition, method, object, slot

TclOO                                                  0.3                                          define(3tcl)