Provided by: tcllib_1.21+dfsg-1_all bug

NAME

       snit - Snit's Not Incr Tcl

SYNOPSIS

       package require Tcl  8.5

       package require snit  ?2.3.2?

       snit::type name definition

       typevariable name ?-array? ?value?

       typemethod name arglist body

       typeconstructor body

       variable name ?-array? ?value?

       method name arglist body

       option namespec ?defaultValue?

       option namespec ?options...?

       constructor arglist body

       destructor body

       proc name args body

       delegate method name to comp ?as target?

       delegate method name ?to comp? using pattern

       delegate method * ?to comp? ?using pattern? ?except exceptions?

       delegate option namespec to comp

       delegate option namespec to comp as target

       delegate option * to comp

       delegate option * to comp except exceptions

       component comp ?-public method? ?-inherit flag?

       delegate typemethod name to comp ?as target?

       delegate typemethod name ?to comp? using pattern

       delegate typemethod * ?to comp? ?using pattern? ?except exceptions?

       typecomponent comp ?-public typemethod? ?-inherit flag?

       pragma ?options...?

       expose comp

       expose comp as method

       onconfigure name arglist body

       oncget name body

       snit::widget name definition

       widgetclass name

       hulltype type

       snit::widgetadaptor name definition

       snit::typemethod type name arglist body

       snit::method type name arglist body

       snit::macro name arglist body

       snit::compile which type body

       $type typemethod args...

       $type create name ?option value ...?

       $type info typevars ?pattern?

       $type info typemethods ?pattern?

       $type info args method

       $type info body method

       $type info default method aname varname

       $type info instances ?pattern?

       $type destroy

       $object method args...

       $object configure ?option? ?value? ...

       $object configurelist optionlist

       $object cget option

       $object destroy

       $object info type

       $object info vars ?pattern?

       $object info typevars ?pattern?

       $object info typemethods ?pattern?

       $object info options ?pattern?

       $object info methods ?pattern?

       $object info args method

       $object info body method

       $object info default method aname varname

       mymethod name ?args...?

       mytypemethod name ?args...?

       myproc name ?args...?

       myvar name

       mytypevar name

       from argvName option ?defvalue?

       install compName using objType objName args...

       installhull using widgetType args...

       installhull name

       variable name

       typevariable name

       varname name

       typevarname name

       codename name

       snit::boolean validate ?value?

       snit::boolean name

       snit::double validate ?value?

       snit::double name ?option value...?

       snit::enum validate ?value?

       snit::enum name ?option value...?

       snit::fpixels validate ?value?

       snit::fpixels name ?option value...?

       snit::integer validate ?value?

       snit::integer name ?option value...?

       snit::listtype validate ?value?

       snit::listtype name ?option value...?

       snit::pixels validate ?value?

       snit::pixels name ?option value...?

       snit::stringtype validate ?value?

       snit::stringtype name ?option value...?

       snit::window validate ?value?

       snit::window name

________________________________________________________________________________________________________________

DESCRIPTION

       Snit is a pure Tcl object and megawidget system.  It's unique among Tcl object systems in that it's based
       not on inheritance but on delegation.  Object systems based on inheritance only allow you to inherit from
       classes  defined  using the same system, which is limiting.  In Tcl, an object is anything that acts like
       an object; it shouldn't matter how the object was implemented.   Snit  is  intended  to  help  you  build
       applications  out of the materials at hand; thus, Snit is designed to be able to incorporate and build on
       any object, whether it's a hand-coded object, a Tk widget, an  Incr  Tcl  object,  a  BWidget  or  almost
       anything else.

       This  man  page  is  intended  to  be  a reference only; see the accompanying snitfaq for a gentler, more
       tutorial introduction to Snit concepts.

SNIT VERSIONS

       This man page covers both Snit 2.2 and Snit 1.3.  The primary difference  between  the  two  versions  is
       simply that Snit 2.2 contains speed optimizations based on new features of Tcl 8.5; Snit 1.3 supports all
       of  Tcl 8.3, 8.4 and Tcl 8.5.  There are a few minor inconsistencies; they are flagged in the body of the
       man page with the label "Snit 1.x Incompatibility"; they are also discussed in the snitfaq.

REFERENCE

   TYPE AND WIDGET DEFINITIONS
       Snit provides the following commands for defining new types:

       snit::type name definition
              Defines a new abstract data type called name.  If name is not a fully qualified command  name,  it
              is  assumed  to be a name in the namespace in which the snit::type command was called (usually the
              global namespace).  It returns the fully qualified name of the new type.

              The type name is then a command that is used to create objects of the new type, along  with  other
              activities.

              The snit::type definition block is a script that may contain the following definitions:

              typevariable name ?-array? ?value?
                     Defines  a type variable with the specified name, and optionally the specified value.  Type
                     variables are shared by all instances of the type.  If the -array option is included,  then
                     value should be a dictionary; it will be assigned to the variable using array set.

              typemethod name arglist body
                     Defines  a  type  method,  a  subcommand  of the new type command, with the specified name,
                     argument list, and body.  The arglist is a normal Tcl argument list and may contain default
                     arguments and the args argument; however, it may not contain the argument names type, self,
                     selfns, or win.

                     The variable type is automatically defined in the body to the type's fully-qualified  name.
                     In addition, type variables are automatically visible in the body of every type method.

                     If the name consists of two or more tokens, Snit handles it specially:

                         typemethod {a b} {arg} { puts "Got $arg" }

                     This  statement  implicitly  defines a type method called a which has a subcommand b.  b is
                     called like this:

                         $type a b "Hello, world!"

                     a may have any number of subcommands.  This makes it  possible  to  define  a  hierarchical
                     command structure; see method, below, for more examples.

                     Type  methods  can  call  commands  from the namespace in which the type is defined without
                     importing them, e.g., if the type  name  is  ::parentns::typename,  then  the  type's  type
                     methods  can  call  ::parentns::someproc  just as someproc.  Snit 1.x Incompatibility: This
                     does not work in Snit 1.x, as it depends on namespace path, a new command in Tcl 8.5.

                     Snit 1.x Incompatibility: In Snit 1.x, the following  following  two  calls  to  this  type
                     method are equivalent:

                         $type a b "Hello, world!"
                         $type {a b} "Hello, world!"

                     In Snit 2.2, the second form is invalid.

              typeconstructor body
                     The  type  constructor's  body  is  executed  once  when  the  type is first defined; it is
                     typically used to initialize array-valued type variables and  to  add  entries  to  The  Tk
                     Option Database.

                     The  variable  type  is  automatically  defined in the body, and contains the type's fully-
                     qualified name.  In addition, type variables are automatically visible in the body  of  the
                     type constructor.

                     A type may define at most one type constructor.

                     The  type  constructor  can  call  commands from the namespace in which the type is defined
                     without importing them, e.g., if the type  name  is  ::parentns::typename,  then  the  type
                     constructor can call ::parentns::someproc just as someproc.  Snit 1.x Incompatibility: This
                     does not work in Snit 1.x, as it depends on namespace path, a new command in Tcl 8.5.

              variable name ?-array? ?value?
                     Defines  an  instance  variable,  a  private variable associated with each instance of this
                     type, and optionally its initial value.  If the  -array  option  is  included,  then  value
                     should be a dictionary; it will be assigned to the variable using array set.

              method name arglist body
                     Defines  an instance method, a subcommand of each instance of this type, with the specified
                     name, argument list and body.  The arglist is a normal Tcl argument list  and  may  contain
                     default arguments and the args argument.

                     The  method  is implicitly passed the following arguments as well: type, which contains the
                     fully-qualified type name; self, which contains the current instance command name;  selfns,
                     which  contains  the  name of the instance's private namespace; and win, which contains the
                     original instance name.  Consequently, the arglist may not contain the argument names type,
                     self, selfns, or win.

                     An instance method defined in this way is said to be locally defined.

                     Type and instance variables are automatically visible in all instance methods.  If the type
                     has locally defined options, the options array is also visible.

                     If the name consists of two or more tokens, Snit handles it specially:

                         method {a b} {} { ... }

                     This statement implicitly defines a method called a which has a subcommand b.  b is  called
                     like this:

                         $self a b "Hello, world!"

                     a  may  have  any  number  of subcommands.  This makes it possible to define a hierarchical
                     command structure:

                     % snit::type dog {
                         method {tail wag}   {} {return "Wag, wag"}
                         method {tail droop} {} {return "Droop, droop"}
                     }
                     ::dog
                     % dog spot
                     ::spot
                     % spot tail wag
                     Wag, wag
                     % spot tail droop
                     Droop, droop
                     %

                     What we've done is implicitly defined a "tail" method with subcommands "wag"  and  "droop".
                     Consequently, it's an error to define "tail" explicitly.

                     Methods can call commands from the namespace in which the type is defined without importing
                     them,  e.g.,  if  the  type  name is ::parentns::typename, then the type's methods can call
                     ::parentns::someproc just as someproc.  Snit 1.x Incompatibility: This  does  not  work  in
                     Snit 1.x, as it depends on namespace path, a new command in Tcl 8.5.

                     Snit 1.x Incompatibility: In Snit 1.x, the following following two calls to this method are
                     equivalent:

                         $self a b "Hello, world!"
                         $self {a b} "Hello, world!"

                     In Snit 2.2, the second form is invalid.

              option namespec ?defaultValue?

              option namespec ?options...?
                     Defines  an  option  for  instances of this type, and optionally gives it an initial value.
                     The initial value defaults to the empty string if no defaultValue is specified.

                     An option defined in this way is said to be locally defined.

                     The namespec is a list defining the option's name, resource name, and class name, e.g.:

                         option {-font font Font} {Courier 12}

                     The option name must begin with a hyphen, and must not contain any upper case letters.  The
                     resource  name and class name are optional; if not specified, the resource name defaults to
                     the option name, minus the hyphen, and the class name defaults to the  resource  name  with
                     the  first letter capitalized.  Thus, the following statement is equivalent to the previous
                     example:

                         option -font {Courier 12}

                     See The Tk Option Database for more information about resource and class names.

                     Options are normally set and retrieved using the standard instance  methods  configure  and
                     cget;  within  instance code (method bodies, etc.), option values are available through the
                     options array:

                         set myfont $options(-font)

                     If the type defines any option handlers (e.g., -configuremethod), then it  should  probably
                     use configure and cget to access its options to avoid subtle errors.

                     The option statement may include the following options:

                     -default defvalue
                            Defines the option's default value; the option's default value will be "" otherwise.

                     -readonly flag
                            The  flag  can  be  any  Boolean value recognized by Tcl.  If flag is true, then the
                            option is read-only--it can only be set using configure or configurelist at creation
                            time, i.e., in the type's constructor.

                     -type type
                            Every locally-defined option may define its validation type, which may be either the
                            name of a validation type or a specification for a validation subtype

                            For example, an option may declare that its value must be an integer  by  specifying
                            snit::integer as its validation type:

                                option -number -type snit::integer

                            It  may  also  declare that its value is an integer between 1 and 10 by specifying a
                            validation subtype:

                                option -number -type {snit::integer -min 1 -max 10}

                            If a validation type or subtype is defined for an option, then it will  be  used  to
                            validate  the  option's  value  whenever  it is changed by the object's configure or
                            configurelist methods.  In  addition,  all  such  options  will  have  their  values
                            validated automatically immediately after the constructor executes.

                            Snit  defines  a  family  of validation types and subtypes, and it's quite simple to
                            define new  ones.   See  Validation  Types  for  the  complete  list,  and  Defining
                            Validation Types for an explanation of how to define your own.

                     -cgetmethod methodName
                            Every  locally-defined  option  may  define  a  -cgetmethod;  it  is called when the
                            option's value is retrieved using the  cget  method.   Whatever  the  method's  body
                            returns will be the return value of the call to cget.

                            The named method must take one argument, the option name.  For example, this code is
                            equivalent to (though slower than) Snit's default handling of cget:

                                option -font -cgetmethod GetOption
                                method GetOption {option} {
                                    return $options($option)
                                }

                            Note that it's possible for any number of options to share a -cgetmethod.

                     -configuremethod methodName
                            Every  locally-defined  option  may define a -configuremethod; it is called when the
                            option's value is set using the configure or configurelist methods.  It is the named
                            method's responsibility to save the option's value; in other words, the  value  will
                            not be saved to the options() array unless the method saves it there.

                            The  named  method  must take two arguments, the option name and its new value.  For
                            example, this code is equivalent to (though slower than) Snit's default handling  of
                            configure:

                                option -font -configuremethod SetOption
                                method SetOption {option value} {
                                    set options($option) $value
                                }

                            Note   that   it's   possible   for   any  number  of  options  to  share  a  single
                            -configuremethod.

                     -validatemethod methodName
                            Every locally-defined option may define a -validatemethod; it  is  called  when  the
                            option's  value is set using the configure or configurelist methods, just before the
                            -configuremethod (if any).  It is the named method's responsibility to validate  the
                            option's new value, and to throw an error if the value is invalid.

                            The  named  method  must take two arguments, the option name and its new value.  For
                            example, this code verifies that -flag's value is a valid Boolean value:

                                option -font -validatemethod CheckBoolean
                                method CheckBoolean {option value} {
                                    if {![string is boolean -strict $value]} {
                                        error "option $option must have a boolean value."
                                    }
                                }

                            Note that it's possible for any number of options to share a single -validatemethod.

              constructor arglist body
                     The constructor definition specifies a body of code to be executed when a new  instance  is
                     created.   The  arglist is a normal Tcl argument list and may contain default arguments and
                     the args argument.

                     As with methods, the arguments type, self, selfns, and win are defined implicitly, and  all
                     type and instance variables are automatically visible in its body.

                     If  the  definition doesn't explicitly define the constructor, Snit defines one implicitly.
                     If the type declares at least one option (whether locally or by  delegation),  the  default
                     constructor will be defined as follows:

                         constructor {args} {
                             $self configurelist $args
                         }

                     For  standard  Tk  widget  behavior,  the  argument list should be the single name args, as
                     shown.

                     If the definition defines neither a constructor nor any options, the default constructor is
                     defined as follows:

                         constructor {} {}

                     As with methods, the constructor can call commands from the namespace in which the type  is
                     defined  without  importing  them, e.g., if the type name is ::parentns::typename, then the
                     constructor can call ::parentns::someproc just as someproc.  Snit 1.x Incompatibility: This
                     does not work in Snit 1.x, as it depends on namespace path, a new command in Tcl 8.5.

              destructor body
                     The destructor is used to code any actions that must take place when  an  instance  of  the
                     type is destroyed: typically, the destruction of anything created in the constructor.

                     The  destructor  takes  no  explicit  arguments; as with methods, the arguments type, self,
                     selfns, and  win,  are  defined  implicitly,  and  all  type  and  instance  variables  are
                     automatically  visible in its body.  As with methods, the destructor can call commands from
                     the namespace in which the type is defined without importing them, e.g., if the  type  name
                     is  ::parentns::typename,  then  the  destructor  can  call  ::parentns::someproc  just  as
                     someproc.  Snit 1.x Incompatibility: This does not work in  Snit  1.x,  as  it  depends  on
                     namespace path, a new command in Tcl 8.5.

              proc name args body
                     Defines a new Tcl procedure in the type's namespace.

                     The  defined  proc  differs  from  a  normal  Tcl  proc  in  that  all  type  variables are
                     automatically visible.  The proc can access instance variables as well, provided that it is
                     passed selfns (with precisely that name) as one of its arguments.

                     Although they are not implicitly defined for procs, the argument names type, self, and  win
                     should be avoided.

                     As  with  methods  and typemethods, procs can call commands from the namespace in which the
                     type is defined without importing them, e.g., if the  type  name  is  ::parentns::typename,
                     then  the  proc  can call ::parentns::someproc just as someproc.  Snit 1.x Incompatibility:
                     This does not work in Snit 1.x, as it depends on namespace path, a new command in Tcl 8.5.

              delegate method name to comp ?as target?
                     Delegates method name to component comp.  That  is,  when  method  name  is  called  on  an
                     instance of this type, the method and its arguments will be passed to the named component's
                     command instead.  That is, the following statement

                         delegate method wag to tail

                     is roughly equivalent to this explicitly defined method:

                         method wag {args} {
                             uplevel $tail wag $args
                         }

                     As  with  methods,  the  name may have multiple tokens; in this case, the last token of the
                     name is assumed to be the name of the component's method.

                     The optional as clause allows you to specify the delegated method  name  and  possibly  add
                     some arguments:

                         delegate method wagtail to tail as "wag briskly"

              A method cannot be both locally defined and delegated.

              Note: All forms of delegate method can delegate to both instance components and type components.

              delegate method name ?to comp? using pattern
                     In  this  form  of  the delegate statement, the using clause is used to specify the precise
                     form of the command to which method name name is delegated.  In this form, the to clause is
                     optional, since the chosen command might not involve any particular component.

                     The value of the using clause is a list that may  contain  any  or  all  of  the  following
                     substitution  codes;  these  codes  are  substituted  with the described value to build the
                     delegated command prefix.  Note that the following two statements are equivalent:

                         delegate method wag to tail
                         delegate method wag to tail using "%c %m"

                     Each element of the list becomes a single element of the  delegated  command--it  is  never
                     reparsed as a string.

                     Substitutions:

                     %%     This is replaced with a single "%".  Thus, to pass the string "%c" to the command as
                            an argument, you'd write "%%c".

                     %c     This is replaced with the named component's command.

                     %m     This is replaced with the final token of the method name; if the method name has one
                            token, this is identical to %M.

                     %M     This  is  replaced by the method name; if the name consists of multiple tokens, they
                            are joined by space characters.

                     %j     This is replaced by the method name; if the name consists of multiple  tokens,  they
                            are joined by underscores ("_").

                     %t     This is replaced with the fully qualified type name.

                     %n     This is replaced with the name of the instance's private namespace.

                     %s     This is replaced with the name of the instance command.

                     %w     This  is  replaced  with the original name of the instance command; for Snit widgets
                            and widget adaptors, it will be the Tk window name.  It remains  constant,  even  if
                            the instance command is renamed.

              delegate method * ?to comp? ?using pattern? ?except exceptions?
                     The  form  delegate method * delegates all unknown method names to the specified component.
                     The except clause can be used to specify a list of exceptions, i.e., method names that will
                     not be so delegated. The using clause is  defined  as  given  above.   In  this  form,  the
                     statement must contain the to clause, the using clause, or both.

                     In  fact,  the "*" can be a list of two or more tokens whose last element is "*", as in the
                     following example:

                         delegate method {tail *} to tail

                     This implicitly defines the method tail whose subcommands will be  delegated  to  the  tail
                     component.

              delegate option namespec to comp

              delegate option namespec to comp as target

              delegate option * to comp

              delegate option * to comp except exceptions
                     Defines  a delegated option; the namespec is defined as for the option statement.  When the
                     configure, configurelist, or cget instance method is used to set or retrieve  the  option's
                     value,  the equivalent configure or cget command will be applied to the component as though
                     the option was defined with the following -configuremethod and -cgetmethod:

                         method ConfigureMethod {option value} {
                             $comp configure $option $value
                         }

                         method CgetMethod {option} {
                             return [$comp cget $option]
                         }

                     Note that delegated options never appear in the options array.

                     If the as clause is specified, then the target option name is used in place of name.

                     The form delegate option * delegates all unknown options to the specified  component.   The
                     except clause can be used to specify a list of exceptions, i.e., option names that will not
                     be so delegated.

                     Warning: options can only be delegated to a component if it supports the configure and cget
                     instance methods.

                     An option cannot be both locally defined and delegated.  TBD: Continue from here.

              component comp ?-public method? ?-inherit flag?
                     Explicitly  declares  a  component  called  comp, and automatically defines the component's
                     instance variable.

                     If the -public option is specified, then the option is made public  by  defining  a  method
                     whose  subcommands  are  delegated  to  the  component  e.g.,  specifying -public mycomp is
                     equivalent to the following:

                         component mycomp
                         delegate method {mymethod *} to mycomp

                     If the -inherit option is specified, then flag must be a Boolean value;  if  flag  is  true
                     then  all  unknown  methods  and  options  will  be  delegated to this component.  The name
                     -inherit implies that instances of this new type inherit,  in  a  sense,  the  methods  and
                     options of the component. That is, -inherit yes is equivalent to:

                         component mycomp
                         delegate option * to mycomp
                         delegate method * to mycomp

              delegate typemethod name to comp ?as target?
                     Delegates  type  method  name  to  type  component comp.  That is, when type method name is
                     called on this type, the type method and its arguments will be passed  to  the  named  type
                     component's command instead.  That is, the following statement

                         delegate typemethod lostdogs to pound

                     is roughly equivalent to this explicitly defined method:

                         typemethod lostdogs {args} {
                             uplevel $pound lostdogs $args
                         }

                     As  with  type  methods, the name may have multiple tokens; in this case, the last token of
                     the name is assumed to be the name of the component's method.

                     The optional as clause allows you to specify the delegated method  name  and  possibly  add
                     some arguments:

                         delegate typemethod lostdogs to pound as "get lostdogs"

              A type method cannot be both locally defined and delegated.

              delegate typemethod name ?to comp? using pattern
                     In  this  form  of  the delegate statement, the using clause is used to specify the precise
                     form of the command to which type method name name is delegated.   In  this  form,  the  to
                     clause  is  optional,  since  the  chosen  command  might  not  involve any particular type
                     component.

                     The value of the using clause is a list that may  contain  any  or  all  of  the  following
                     substitution  codes;  these  codes  are  substituted  with the described value to build the
                     delegated command prefix.  Note that the following two statements are equivalent:

                         delegate typemethod lostdogs to pound
                         delegate typemethod lostdogs to pound using "%c %m"

                     Each element of the list becomes a single element of the  delegated  command--it  is  never
                     reparsed as a string.

                     Substitutions:

                     %%     This is replaced with a single "%".  Thus, to pass the string "%c" to the command as
                            an argument, you'd write "%%c".

                     %c     This is replaced with the named type component's command.

                     %m     This  is  replaced  with the final token of the type method name; if the type method
                            name has one token, this is identical to %M.

                     %M     This is replaced by the type method name; if the name consists of  multiple  tokens,
                            they are joined by space characters.

                     %j     This  is  replaced by the type method name; if the name consists of multiple tokens,
                            they are joined by underscores ("_").

                     %t     This is replaced with the fully qualified type name.

              delegate typemethod * ?to comp? ?using pattern? ?except exceptions?
                     The form delegate typemethod * delegates all unknown type method  names  to  the  specified
                     type  component.  The except clause can be used to specify a list of exceptions, i.e., type
                     method names that will not be so delegated. The using clause is defined as given above.  In
                     this form, the statement must contain the to clause, the using clause, or both.

                     Note: By default, Snit interprets $type foo, where foo is not a  defined  type  method,  as
                     equivalent  to  $type  create foo, where foo is the name of a new instance of the type.  If
                     you use delegate typemethod *, then the create type method must always be used explicitly.

                     The "*" can be a list of two or more tokens whose last element is "*", as in the  following
                     example:

                         delegate typemethod {tail *} to tail

                     This  implicitly  defines  the  type method tail whose subcommands will be delegated to the
                     tail type component.

              typecomponent comp ?-public typemethod? ?-inherit flag?
                     Explicitly declares a type component called comp, and automatically defines the component's
                     type variable.  A type component is an arbitrary command to which type methods and instance
                     methods can be delegated; the command's name is stored in a type variable.

                     If the -public option is specified, then the type component is made public  by  defining  a
                     typemethod  whose subcommands are delegated to the type component, e.g., specifying -public
                     mytypemethod is equivalent to the following:

                         typecomponent mycomp
                         delegate typemethod {mytypemethod *} to mycomp

                     If the -inherit option is specified, then flag must be a Boolean value;  if  flag  is  true
                     then  all  unknown  type methods will be delegated to this type component. (See the note on
                     "delegate typemethod *", above.) The name -inherit implies that this type  inherits,  in  a
                     sense, the behavior of the type component. That is, -inherit yes is equivalent to:

                         typecomponent mycomp
                         delegate typemethod * to mycomp

              pragma ?options...?
                     The  pragma  statement  provides  control  over  how  Snit  generates a type.  It takes the
                     following options; in each case, flag must be a Boolean value recognized by Tcl,  e.g.,  0,
                     1, yes, no, and so on.

                     By  setting  the  -hastypeinfo,  -hastypedestroy,  and  -hasinstances  pragmas to false and
                     defining appropriate  type  methods,  you  can  create  an  ensemble  command  without  any
                     extraneous behavior.

                     -canreplace flag
                            If false (the default) Snit will not create an instance of a snit::type that has the
                            same  name as an existing command; this prevents subtle errors.  Setting this pragma
                            to true restores the behavior of Snit V0.93 and earlier versions.

                     -hastypeinfo flag
                            If true (the default), the generated type will have a type method called  info  that
                            is used for type introspection; the info type method is documented below.  If false,
                            it will not.

                     -hastypedestroy flag
                            If  true  (the  default),  the generated type will have a type method called destroy
                            that is used to destroy the type and all of its instances.  The destroy type  method
                            is documented below.  If false, it will not.

                     -hastypemethods flag
                            If true (the default), the generated type's type command will have subcommands (type
                            methods)  as  usual.  If false, the type command will serve only to create instances
                            of the type; the first argument is the instance name.

                            This pragma and -hasinstances cannot both be set false.

                     -hasinstances flag
                            If true (the default), the generated type will have a type method called create that
                            is used to create instances of the type, along with a  variety  of  instance-related
                            features.  If false, it will not.

                            This pragma and -hastypemethods cannot both be set false.

                     -hasinfo flag
                            If  true (the default), instances of the generated type will have an instance method
                            called info that is used for instance introspection; the info method  is  documented
                            below.  If false, it will not.

                     -simpledispatch flag
                            This  pragma  is  intended  to  make simple, heavily-used abstract data types (e.g.,
                            stacks and queues) more efficient.

                            If false (the default), instance methods are dispatched normally.  If true, a faster
                            dispatching  scheme  is  used  instead.   The  speed  comes   at   a   price;   with
                            -simpledispatch yes you get the following limitations:

                            •      Methods cannot be delegated.

                            •      uplevel  and  upvar do not work as expected: the caller's scope is two levels
                                   up rather than one.

                            •      The option-handling methods (cget, configure,  and  configurelist)  are  very
                                   slightly slower.

              expose comp

              expose comp as method
                     Deprecated.  To expose component comp publicly, use component's -public option.

              onconfigure name arglist body
                     Deprecated.  Define option's -configuremethod option instead.

                     As of version 0.95, the following definitions,

                         option -myoption
                         onconfigure -myoption {value} {
                             # Code to save the option's value
                         }

                     are implemented as follows:

                         option -myoption -configuremethod _configure-myoption
                         method _configure-myoption {_option value} {
                             # Code to save the option's value
                         }

              oncget name body
                     Deprecated.  Define option's -cgetmethod option instead.

                     As of version 0.95, the following definitions,

                         option -myoption
                         oncget -myoption {
                             # Code to return the option's value
                         }

                     are implemented as follows:

                         option -myoption -cgetmethod _cget-myoption
                         method _cget-myoption {_option} {
                             # Code to return the option's value
                         }

       snit::widget name definition
              This command defines a Snit megawidget type with the specified name.  The definition is defined as
              for snit::type.  A snit::widget differs from a snit::type in these ways:

              •      Every  instance of a snit::widget has an automatically-created component called hull, which
                     is normally a Tk frame widget.  Other widgets created as part of  the  megawidget  will  be
                     created within this widget.

                     The hull component is initially created with the requested widget name; then Snit does some
                     magic,  renaming  the  hull component and installing its own instance command in its place.
                     The hull component's new name is saved in an instance variable called hull.

              •      The name of an instance must be valid Tk window name, and the parent window must exist.

              A snit::widget definition can include any of statements allowed in a  snit::type  definition,  and
              may also include the following:

              widgetclass name
                     Sets  the  snit::widget's  widget class to name, overriding the default.  See The Tk Option
                     Database for more information.

              hulltype type
                     Determines the kind of widget used as the snit::widget's hull.  The type may be frame  (the
                     default),   toplevel,   labelframe;   the   qualified   equivalents  of  these,  tk::frame,
                     tk::toplevel,  and  tk::labelframe;  or,  if  available,  the  equivalent   Tile   widgets:
                     ttk::frame,  ttk::toplevel, and ttk::labelframe.  In practice, any widget that supports the
                     -class option can be used as a  hull  widget  by  lappend'ing  its  name  to  the  variable
                     snit::hulltypes.

       snit::widgetadaptor name definition
              This command defines a Snit megawidget type with the specified name.  It differs from snit::widget
              in  that  the  instance's  hull  component  is  not  created  automatically, but is created in the
              constructor and installed using the installhull command.  Once the hull is installed, its instance
              command is renamed and replaced as with normal  snit::widgets.   The  original  command  is  again
              accessible in the instance variable hull.

              Note that in general it is not possible to change the widget class of a snit::widgetadaptor's hull
              widget.

              See  The  Tk  Option Database for information on how snit::widgetadaptors interact with the option
              database.

       snit::typemethod type name arglist body
              Defines a new type method (or redefines an existing type method) for a previously existing type.

       snit::method type name arglist body
              Defines a new instance method (or redefines an existing instance method) for a previously existing
              type.  Note that delegated instance methods can't be redefined.

       snit::macro name arglist body
              Defines a Snit macro with the specified name, arglist, and body.  Macros are used  to  define  new
              type and widget definition statements in terms of the statements defined in this man page.

              A  macro  is  simply  a Tcl proc that is defined in the slave interpreter used to compile type and
              widget definitions.  Thus, macros have access to all of the type and widget definition statements.
              See Macros and Meta-programming for more details.

              The macro name cannot be the same as any  standard  Tcl  command,  or  any  Snit  type  or  widget
              definition  statement, e.g., you can't redefine the method or delegate statements, or the standard
              set, list, or string commands.

       snit::compile which type body
              Snit defines a type, widget, or widgetadaptor by "compiling" the definition  into  a  Tcl  script;
              this script is then evaluated in the Tcl interpreter, which actually defines the new type.

              This  command  exposes the "compiler".  Given a definition body for the named type, where which is
              type, widget, or widgetadaptor, snit::compile returns a list of two elements.  The  first  element
              is the fully qualified type name; the second element is the definition script.

              snit::compile  is useful when additional processing must be done on the Snit-generated code--if it
              must be instrumented, for example, or run  through  the  TclDevKit  compiler.   In  addition,  the
              returned  script  could  be  saved  in  a  ".tcl"  file  and used to define the type as part of an
              application or library, thus saving the compilation overhead at application start-up.   Note  that
              the same version of Snit must be used at run-time as at compile-time.

   THE TYPE COMMAND
       A  type  or widget definition creates a type command, which is used to create instances of the type.  The
       type command has this form:

       $type typemethod args...
              The typemethod can be any of the Standard Type Methods (e.g., create), or any type method  defined
              in the type definition.  The subsequent args depend on the specific typemethod chosen.

              The  type command is most often used to create new instances of the type; hence, the create method
              is assumed if the first argument to the type command doesn't name a valid type method, unless  the
              type definition includes delegate typemethod * or the -hasinstances pragma is set to false.

              Furthermore, if the -hastypemethods pragma is false, then Snit type commands can be called with no
              arguments  at  all;  in  this  case,  the  type  command creates an instance with an automatically
              generated name.  In other words, provided that the -hastypemethods pragma is false  and  the  type
              has instances, the following commands are equivalent:

              snit::type dog { ... }

              set mydog [dog create %AUTO%]
              set mydog [dog %AUTO%]
              set mydog [dog]

              This doesn't work for Snit widgets, for obvious reasons.

              Snit  1.x Incompatibility: In Snit 1.x, the above behavior is available whether -hastypemethods is
              true (the default) or false.

   STANDARD TYPE METHODS
       In addition to any type methods in the type's definition, all type and widget commands will usually  have
       at least the following subcommands:

       $type create name ?option value ...?
              Creates  a  new  instance  of  the  type,  giving  it  the  specified  name and calling the type's
              constructor.

              For snit::types, if name is not a fully-qualified command name, it is assumed to be a name in  the
              namespace  in  which  the  call  to  snit::type  appears.   The method returns the fully-qualified
              instance name.

              For snit::widgets and snit::widgetadaptors, name must be a valid widget name; the  method  returns
              the widget name.

              So  long  as  name  does  not conflict with any defined type method name the create keyword may be
              omitted, unless the type definition includes delegate typemethod * or the -hasinstances pragma  is
              set to false.

              If  the  name  includes the string %AUTO%, it will be replaced with the string $type$counter where
              $type is the type name and $counter is a counter that increments each time %AUTO% is used for this
              type.

              By default, any arguments following the name will be a list of  option  names  and  their  values;
              however, a type's constructor can specify a different argument list.

              As of Snit V0.95, create will throw an error if the name is the same as any existing command--note
              that  this  was  always  true  for  snit::widgets  and  snit::widgetadaptors.  You can restore the
              previous behavior using the -canreplace pragma.

       $type info typevars ?pattern?
              Returns a list of the type's type variables (excluding  Snit  internal  variables);  all  variable
              names are fully-qualified.

              If  pattern  is  given, it's used as a string match pattern; only names that match the pattern are
              returned.

       $type info typemethods ?pattern?
              Returns a list of the names of the  type's type  methods.   If  the  type  has  hierarchical  type
              methods, whether locally-defined or delegated, only the first word of each will be included in the
              list.

              If  the  type  definition  includes delegate typemethod *, the list will include only the names of
              those implicitly delegated type methods that have been called at least once and are still  in  the
              type method cache.

              If  pattern  is  given, it's used as a string match pattern; only names that match the pattern are
              returned.

       $type info args method
              Returns a list containing the names of the arguments to the type's method, in order.  This  method
              cannot be applied to delegated type methods.

       $type info body method
              Returns the body of typemethod method. This method cannot be applied to delegated type methods.

       $type info default method aname varname
              Returns  a  boolean value indicating whether the argument aname of the type's method has a default
              value (true) or not (false). If the argument has a default its value is placed into  the  variable
              varname.

       $type info instances ?pattern?
              Returns  a  list  of  the type's instances.  For snit::types, it will be a list of fully-qualified
              instance names; for snit::widgets, it will be a list of Tk widget names.

              If pattern is given, it's used as a string match pattern; only names that match  the  pattern  are
              returned.

              Snit 1.x Incompatibility:  In Snit 1.x, the full multi-word names of hierarchical type methods are
              included in the return value.

       $type destroy
              Destroys the type's instances, the type's namespace, and the type command itself.

   THE INSTANCE COMMAND
       A  Snit  type  or  widget's create type method creates objects of the type; each object has a unique name
       that is also a Tcl command.  This command is used to access the object's methods and data, and  has  this
       form:

       $object method args...
              The method can be any of the Standard Instance Methods, or any instance method defined in the type
              definition.  The subsequent args depend on the specific method chosen.

   STANDARD INSTANCE METHODS
       In  addition  to  any  delegated  or  locally-defined instance methods in the type's definition, all Snit
       objects will have at least the following subcommands:

       $object configure ?option? ?value? ...
              Assigns new values to one or more options.  If called with one argument, an option name, returns a
              list describing the option, as Tk widgets do; if called with no arguments, returns a list of lists
              describing all options, as Tk widgets do.

              Warning: This information will be available for delegated options only if the component  to  which
              they are delegated has a configure method that returns this same kind of information.

              Note: Snit defines this method only if the type has at least one option.

       $object configurelist optionlist
              Like configure, but takes one argument, a list of options and their values.  It's mostly useful in
              the type constructor, but can be used anywhere.

              Note: Snit defines this method only if the type has at least one option.

       $object cget option
              Returns the option's value.

              Note: Snit defines this method only if the type has at least one option.

       $object destroy
              Destroys the object, calling the destructor and freeing all related memory.

              Note:  The destroy method isn't defined for snit::widget or snit::widgetadaptor objects; instances
              of these are destroyed by calling Tk's destroy command, just as normal widgets are.

       $object info type
              Returns the instance's type.

       $object info vars ?pattern?
              Returns a list of the object's instance variables (excluding Snit internal variables).  The  names
              are fully qualified.

              If  pattern  is  given, it's used as a string match pattern; only names that match the pattern are
              returned.

       $object info typevars ?pattern?
              Returns a list of the object's type's type variables (excluding  Snit  internal  variables).   The
              names are fully qualified.

              If  pattern  is  given, it's used as a string match pattern; only names that match the pattern are
              returned.

       $object info typemethods ?pattern?
              Returns a list of the names of the  type's type  methods.   If  the  type  has  hierarchical  type
              methods, whether locally-defined or delegated, only the first word of each will be included in the
              list.

              If  the  type  definition  includes delegate typemethod *, the list will include only the names of
              those implicitly delegated type methods that have been called at least once and are still  in  the
              type method cache.

              If  pattern  is  given, it's used as a string match pattern; only names that match the pattern are
              returned.

              Snit 1.x Incompatibility:  In Snit 1.x, the full multi-word names of hierarchical type methods are
              included in the return value.

       $object info options ?pattern?
              Returns a list of the object's option names.  This always includes local  options  and  explicitly
              delegated  options.   If unknown options are delegated as well, and if the component to which they
              are delegated responds to $object configure like Tk widgets do, then the result will  include  all
              possible unknown options that can be delegated to the component.

              If  pattern  is  given, it's used as a string match pattern; only names that match the pattern are
              returned.

              Note that the return value might be different  for  different  instances  of  the  same  type,  if
              component object types can vary from one instance to another.

       $object info methods ?pattern?
              Returns  a  list  of  the  names of the instance's methods.  If the type has hierarchical methods,
              whether locally-defined or delegated, only the first word of each will be included in the list.

              If the type definition includes delegate method *, the list will include only the names  of  those
              implicitly  delegated  methods  that  have  been  called at least once and are still in the method
              cache.

              If pattern is given, it's used as a string match pattern; only names that match  the  pattern  are
              returned.

              Snit 1.x Incompatibility:  In Snit 1.x, the full multi-word names of hierarchical type methods are
              included in the return value.

       $object info args method
              Returns  a  list  containing  the  names of the arguments to the instance's method, in order. This
              method cannot be applied to delegated methods.

       $object info body method
              Returns the body of the instance's method method. This  method  cannot  be  applied  to  delegated
              methods.

       $object info default method aname varname
              Returns  a  boolean  value  indicating  whether  the argument aname of the instance's method has a
              default value (true) or not (false). If the argument has a default its value is  placed  into  the
              variable varname.

   COMMANDS FOR USE IN OBJECT CODE
       Snit  defines  the  following  commands  for  use  in your object code: that is, for use in type methods,
       instance methods, constructors, destructors, onconfigure handlers, oncget handlers, and procs.   They  do
       not  reside  in  the ::snit:: namespace; instead, they are created with the type, and can be used without
       qualification.

       mymethod name ?args...?
              The mymethod command is used for formatting callback commands to be passed to other  objects.   It
              returns  a  command that when called will invoke method name with the specified arguments, plus of
              course any arguments added by the caller.  In other words, both of  the  following  commands  will
              cause the object's dosomething method to be called when the $button is pressed:

                  $button configure -command [list $self dosomething myargument]

                  $button configure -command [mymethod dosomething myargument]

              The  chief  distinction  between  the  two  is that the latter form will not break if the object's
              command is renamed.

       mytypemethod name ?args...?
              The mytypemethod command is used for formatting callback commands to be passed to  other  objects.
              It  returns  a command that when called will invoke type method name with the specified arguments,
              plus of course any arguments added by the caller.  In other words, both of the following  commands
              will cause the object's dosomething type method to be called when $button is pressed:

                  $button configure -command [list $type dosomething myargument]

                  $button configure -command [mytypemethod dosomething myargument]

              Type  commands  cannot be renamed, so in practice there's little difference between the two forms.
              mytypemethod is provided for parallelism with mymethod.

       myproc name ?args...?
              The myproc command is used for formatting callback commands to be passed  to  other  objects.   It
              returns  a  command  that when called will invoke the type proc name with the specified arguments,
              plus of course any arguments added by the caller.  In other words, both of the following  commands
              will cause the object's dosomething proc to be called when $button is pressed:

                  $button configure -command [list ${type}::dosomething myargument]

                  $button configure -command [myproc dosomething myargument]

       myvar name
              Given an instance variable name, returns the fully qualified name.  Use this if you're passing the
              variable to some other object, e.g., as a -textvariable to a Tk label widget.

       mytypevar name
              Given  an  type  variable  name, returns the fully qualified name.  Use this if you're passing the
              variable to some other object, e.g., as a -textvariable to a Tk label widget.

       from argvName option ?defvalue?
              The from command plucks an option value from a list of options and their values, such as is passed
              into a type's constructor.  argvName must be the name of a variable containing such a list; option
              is the name of the specific option.

              from looks for option in the option list.  If it is found, it and its value are removed  from  the
              list,  and  the  value  is  returned.   If option doesn't appear in the list, then the defvalue is
              returned.  If the option is locally-defined option,  and  defvalue  is  not  specified,  then  the
              option's default value as specified in the type definition will be returned instead.

       install compName using objType objName args...
              Creates  a  new  object  of  type objType called objName and installs it as component compName, as
              described in Components and Delegation.  Any additional args... are passed along with the name  to
              the objType command.  If this is a snit::type, then the following two commands are equivalent:

                  install myComp using myObjType $self.myComp args...

                  set myComp [myObjType $self.myComp args...]

              Note  that  whichever method is used, compName must still be declared in the type definition using
              component, or must be referenced in at least one delegate statement.

              If this is a snit::widget or snit::widgetadaptor, and if options have been delegated to  component
              compName,  then  those options will receive default values from the Tk option database.  Note that
              it doesn't matter whether the component to be installed is a widget or not.   See  The  Tk  Option
              Database for more information.

              install  cannot  be used to install type components; just assign the type component's command name
              to the type component's variable instead.

       installhull using widgetType args...

       installhull name
              The constructor of a snit::widgetadaptor must create a widget to be the object's  hull  component;
              the  widget  is  installed  as  the  hull  component  using this command.  Note that the installed
              widget's name must be $win.  This command has two forms.

              The first form specifies the widgetType and the args...  (that is, the hardcoded option  list)  to
              use  in  creating the hull.  Given this form, installhull creates the hull widget, and initializes
              any options delegated to the hull from the Tk option database.

              In the second form, the hull widget has already been created; note that its name must  be  "$win".
              In  this  case,  the Tk option database is not queried for any options delegated to the hull.  The
              longer form is preferred; however, the shorter form  allows  the  programmer  to  adapt  a  widget
              created  elsewhere,  which  is  sometimes  useful.   For example, it can be used to adapt a "page"
              widget created by a BWidgets tabbed notebook or pages manager widget.

              See The Tk Option  Database  for  more  information  about  snit::widgetadaptors  and  the  option
              database.

       variable name
              Normally,  instance  variables are defined in the type definition along with the options, methods,
              and so forth; such instance variables are automatically visible in all instance code (e.g., method
              bodies).  However, instance code can use the variable command to declare instance  variables  that
              don't  appear in the type definition, and also to bring variables from other namespaces into scope
              in the usual way.

              It's generally clearest to define  all  instance  variables  in  the  type  definition,  and  omit
              declaring them in methods and so forth.

              Note that this is an instance-specific version of the standard Tcl ::variable command.

       typevariable name
              Normally,  type  variables  are defined in the type definition, along with the instance variables;
              such type variables are automatically visible in all of the type's code.  However,  type  methods,
              instance  methods and so forth can use typevariable to declare type variables that don't appear in
              the type definition.

              It's generally clearest to declare all type variables in the type definition, and  omit  declaring
              them in methods, type methods, etc.

       varname name
              Deprecated.  Use myvar instead.

              Given an instance variable name, returns the fully qualified name.  Use this if you're passing the
              variable to some other object, e.g., as a -textvariable to a Tk label widget.

       typevarname name
              Deprecated.  Use mytypevar instead.

              Given a type variable name, returns the fully qualified name.  Use this if you're passing the type
              variable to some other object, e.g., as a -textvariable to a Tk label widget.

       codename name
              Deprecated.   Use  myproc  instead.  Given the name of a proc (but not a type or instance method),
              returns the fully-qualified command name, suitable for passing as a callback.

   COMPONENTS AND DELEGATION
       When an object includes other objects, as when a toolbar contains buttons or a  GUI  object  contains  an
       object that references a database, the included object is called a component.  The standard way to handle
       component  objects  owned  by a Snit object is to declare them using component, which creates a component
       instance variable.  In the following example, a dog object has a tail object:

                  snit::type dog {
                      component mytail

                      constructor {args} {
                          set mytail [tail %AUTO% -partof $self]
                          $self configurelist $args
                      }

                      method wag {} {
                          $mytail wag
                      }
                  }

                  snit::type tail {
                      option -length 5
                      option -partof
                      method wag {} { return "Wag, wag, wag."}
                  }

       Because the tail object's name is stored in an instance variable, it's easily accessible in any method.

       The install command provides an alternate way to create and install the component:

                  snit::type dog {
                      component mytail

                      constructor {args} {
                          install mytail using tail %AUTO% -partof $self
                          $self configurelist $args
                      }

                      method wag {} {
                          $mytail wag
                      }
                  }

       For snit::types, the two methods are equivalent; for snit::widgets and snit::widgetadaptors, the  install
       command properly initializes the widget's options by querying The Tk Option Database.

       In  the  above examples, the dog object's wag method simply calls the tail component's wag method.  In OO
       jargon, this is called delegation.  Snit provides an easier way to do this:

                  snit::type dog {
                      delegate method wag to mytail

                      constructor {args} {
                          install mytail using tail %AUTO% -partof $self
                          $self configurelist $args
                      }
                  }

       The delegate statement in the type definition implicitly defines the instance variable mytail to hold the
       component's name (though it's good form to use component to declare it explicitly); it also  defines  the
       dog object's wag method, delegating it to the mytail component.

       If desired, all otherwise unknown methods can be delegated to a specific component:

                  snit::type dog {
                delegate method * to mytail

                constructor {args} {
                    set mytail [tail %AUTO% -partof $self]
                    $self configurelist $args
                }

                method bark { return "Bark, bark, bark!" }
                  }

       In  this case, a dog object will handle its own bark method; but wag will be passed along to mytail.  Any
       other method, being recognized by neither dog nor tail, will simply raise an error.

       Option delegation is similar to method delegation,  except  for  the  interactions  with  the  Tk  option
       database; this is described in The Tk Option Database.

   TYPE COMPONENTS AND DELEGATION
       The  relationship  between  type  components  and  instance  components is identical to that between type
       variables and instance variables, and that between  type  methods  and  instance  methods.   Just  as  an
       instance  component  is  an  instance variable that holds the name of a command, so a type component is a
       type variable that holds the name of a command.  In essence, a  type  component  is  a  component  that's
       shared by every instance of the type.

       Just  as  delegate  method  can  be  used  to  delegate  methods  to instance components, as described in
       Components and Delegation, so  delegate  typemethod  can  be  used  to  delegate  type  methods  to  type
       components.

       Note  also that as of Snit 0.95 delegate method can delegate methods to both instance components and type
       components.

   THE TK OPTION DATABASE
       This section describes how Snit interacts with the Tk option database,  and  assumes  the  reader  has  a
       working  knowledge  of the option database and its uses.  The book Practical Programming in Tcl and Tk by
       Welch et al has a good introduction to the option database, as does Effective Tcl/Tk Programming.

       Snit is implemented so that most of the time it will simply do the right thing with respect to the option
       database, provided that the widget developer does the right thing by Snit.  The body of this section goes
       into great deal about what Snit requires.  The following is a brief statement of  the  requirements,  for
       reference.

       •      If  the  snit::widget's  default  widget  class  is  not  what is desired, set it explicitly using
              widgetclass in the widget definition.

       •      When defining or delegating options, specify the resource and class names explicitly when  if  the
              defaults aren't what you want.

       •      Use installhull using to install the hull for snit::widgetadaptors.

       •      Use install to install all other components.

       The  interaction  of Tk widgets with the option database is a complex thing; the interaction of Snit with
       the option database is even more so, and repays attention to detail.

       Setting the widget class: Every Tk widget has a widget class.  For Tk widgets, the widget class  name  is
       the  just  the widget type name with an initial capital letter, e.g., the widget class for button widgets
       is "Button".

       Similarly, the widget class of a snit::widget defaults to the unqualified type name with the first letter
       capitalized.  For example, the widget class of

                  snit::widget ::mylibrary::scrolledText { ... }

       is "ScrolledText".  The widget class can also be set explicitly using the  widgetclass  statement  within
       the snit::widget definition.

       Any  widget  can  be  used  as  the hulltype provided that it supports the -class option for changing its
       widget class name.  See the discussion of the hulltype command, above.  The user may pass -class  to  the
       widget at instantion.

       The  widget  class  of  a snit::widgetadaptor is just the widget class of its hull widget; this cannot be
       changed unless the hull widget supports -class, in which case it will usually  make  more  sense  to  use
       snit::widget rather than snit::widgetadaptor.

       Setting  option  resource  names  and  classes: In Tk, every option has three names: the option name, the
       resource name, and the class name.  The option name begins with a hyphen and is all lowercase; it's  used
       when creating widgets, and with the configure and cget commands.

       The  resource  and  class  names  are  used to initialize option default values by querying the Tk option
       database.  The resource name is usually just the option name minus the hyphen, but may contain  uppercase
       letters at word boundaries; the class name is usually just the resource name with an initial capital, but
       not always.  For example, here are the option, resource, and class names for several text widget options:

                  -background         background         Background
                  -borderwidth        borderWidth        BorderWidth
                  -insertborderwidth  insertBorderWidth  BorderWidth
                  -padx               padX               Pad

       As  is  easily seen, sometimes the resource and class names can be inferred from the option name, but not
       always.

       Snit options also have a resource name and a class name.  By default, these names follow the  rule  given
       above:  the  resource name is the option name without the hyphen, and the class name is the resource name
       with an initial capital.  This is true for both locally-defined options and explicitly delegated options:

                  snit::widget mywidget {
                      option -background
                      delegate option -borderwidth to hull
                      delegate option * to text
                # ...
                  }

       In this case, the widget class name is "Mywidget".  The widget has the  following  options:  -background,
       which  is  locally  defined,  and  -borderwidth,  which  is  explicitly  delegated; all other widgets are
       delegated to a component called "text", which is probably a Tk text widget.  If so, mywidget has all  the
       same options as a text widget.  The option, resource, and class names are as follows:

                  -background  background  Background
                  -borderwidth borderwidth Borderwidth
                  -padx        padX        Pad

       Note  that  the locally defined option, -background, happens to have the same three names as the standard
       Tk -background option; and -pad, which is delegated implicitly to the text component, has the same  three
       names  for  mywidget  as  it  does  for  the text widget.  -borderwidth, on the other hand, has different
       resource and class  names  than  usual,  because  the  internal  word  "width"  isn't  capitalized.   For
       consistency, it should be; this is done as follows:

                  snit::widget mywidget {
                option -background
                delegate option {-borderwidth borderWidth} to hull
                delegate option * to text
                # ...
                  }

       The class name will default to "BorderWidth", as expected.

       Suppose,  however,  that  mywidget  also  delegated  -padx and -pady to the hull.  In this case, both the
       resource name and the class name must be specified explicitly:

                  snit::widget mywidget {
                option -background
                delegate option {-borderwidth borderWidth} to hull
                delegate option {-padx padX Pad} to hull
                delegate option {-pady padY Pad} to hull
                delegate option * to text
                # ...
                  }

       Querying the option database: If you set your widgetclass and option names as described above, Snit  will
       query  the  option  database when each instance is created, and will generally do the right thing when it
       comes to querying the option database.  The remainder of this section goes into the gory details.

       Initializing locally defined options: When an instance of a snit::widget is created, its locally  defined
       options  are  initialized  as  follows:  each  option's resource and class names are used to query the Tk
       option database.  If the result is non-empty, it is used as the option's default; otherwise, the  default
       hardcoded  in  the type definition is used.  In either case, the default can be overridden by the caller.
       For example,

                  option add *Mywidget.texture pebbled

                  snit::widget mywidget {
                option -texture smooth
                # ...
                  }

                  mywidget .mywidget -texture greasy

       Here, -texture would normally default to "smooth", but because of the entry added to the option  database
       it  defaults  to  "pebbled".   However,  the caller has explicitly overridden the default, and so the new
       widget will be "greasy".

       Initializing options delegated to the hull: A snit::widget's hull is a widget, and given that  its  class
       has been set it is expected to query the option database for itself.  The only exception concerns options
       that are delegated to it with a different name.  Consider the following code:

                  option add *Mywidget.borderWidth 5
                  option add *Mywidget.relief sunken
                  option add *Mywidget.hullbackground red
                  option add *Mywidget.background green

                  snit::widget mywidget {
                delegate option -borderwidth to hull
                delegate option -hullbackground to hull as -background
                delegate option * to hull
                # ...
                  }

                  mywidget .mywidget

                  set A [.mywidget cget -relief]
                  set B [.mywidget cget -hullbackground]
                  set C [.mywidget cget -background]
                  set D [.mywidget cget -borderwidth]

       The question is, what are the values of variables A, B, C and D?

       The  value  of A is "sunken".  The hull is a Tk frame that has been given the widget class "Mywidget"; it
       will automatically query the option database and pick  up  this  value.   Since  the  -relief  option  is
       implicitly delegated to the hull, Snit takes no action.

       The  value  of  B  is  "red".   The hull will automatically pick up the value "green" for its -background
       option, just as it picked up the -relief value.  However, Snit knows that -hullbackground  is  mapped  to
       the  hull's  -background option; hence, it queries the option database for -hullbackground and gets "red"
       and updates the hull accordingly.

       The value of C is also "red", because -background is implicitly delegated to the hull;  thus,  retrieving
       it  is  the same as retrieving -hullbackground.  Note that this case is unusual; in practice, -background
       would probably be explicitly delegated to some other component.

       The value of D is "5", but not for the reason you think.  Note that as it is defined above, the  resource
       name  for -borderwidth defaults to "borderwidth", whereas the option database entry is "borderWidth".  As
       with -relief, the hull picks up its own -borderwidth option  before  Snit  does  anything.   Because  the
       option  is  delegated  under  its own name, Snit assumes that the correct thing has happened, and doesn't
       worry about it any further.

       For snit::widgetadaptors, the case is somewhat altered.  Widget adaptors retain the widget class of their
       hull, and the hull is not created automatically by Snit.   Instead,  the  snit::widgetadaptor  must  call
       installhull in its constructor.  The normal way to do this is as follows:

                  snit::widgetadaptor mywidget {
                # ...
                constructor {args} {
                    # ...
                    installhull using text -foreground white
                    #
                }
                #...
                  }

       In this case, the installhull command will create the hull using a command like this:

                  set hull [text $win -foreground white]

       The  hull is a text widget, so its widget class is "Text".  Just as with snit::widget hulls, Snit assumes
       that it will pick up all of its normal option values automatically; options delegated  from  a  different
       name are initialized from the option database in the same way.

       Initializing  options  delegated  to other components: Non-hull components are matched against the option
       database in two ways.  First, a component widget remains a widget still,  and  therefore  is  initialized
       from  the  option  database  in  the  usual  way.  Second, the option database is queried for all options
       delegated to the component, and the component  is  initialized  accordingly--provided  that  the  install
       command is used to create it.

       Before  option  database  support  was  added  to Snit, the usual way to create a component was to simply
       create it in the constructor and assign its command name to the component variable:

                  snit::widget mywidget {
                delegate option -background to myComp

                constructor {args} {
                    set myComp [text $win.text -foreground black]
                }
                  }

       The drawback of this method is that Snit has no opportunity to initialize the component properly.  Hence,
       the following approach is now used:

                  snit::widget mywidget {
                delegate option -background to myComp

                constructor {args} {
                    install myComp using text $win.text -foreground black
                }
                  }

       The install command does the following:

       •      Builds a list of the options  explicitly  included  in  the  install  command  --  in  this  case,
              -foreground.

       •      Queries the option database for all options delegated explicitly to the named component.

       •      Creates  the  component using the specified command, after inserting into it a list of options and
              values read from the option database.  Thus, the explicitly included  options  (-foreground)  will
              override anything read from the option database.

       •      If  the  widget  definition implicitly delegated options to the component using delegate option *,
              then Snit calls the newly created component's configure method to receive a list  of  all  of  the
              component's  options.   From  this  Snit  builds  a  list  of  options implicitly delegated to the
              component that were not explicitly included in the install command.  For all  such  options,  Snit
              queries the option database and configures the component accordingly.

       Non-widget components: The option database is never queried for snit::types, since it can only be queried
       given  a  Tk  widget  name.   However,  snit::widgets can have non-widget components.  And if options are
       delegated to those components, and if the install command is used to install those components, then  they
       will be initialized from the option database just as widget components are.

   MACROS AND META-PROGRAMMING
       The  snit::macro  command  enables  a certain amount of meta-programming with Snit classes.  For example,
       suppose you like to define properties: instance variables that have set/get  methods.   Your  code  might
       look like this:

                  snit::type dog {
                      variable mood happy

                      method getmood {} {
                          return $mood
                      }

                      method setmood {newmood} {
                          set mood $newmood
                      }
                  }

       That's nine lines of text per property.  Or, you could define the following snit::macro:

                  snit::macro property {name initValue} {
                      variable $name $initValue

                      method get$name {} "return $name"

                      method set$name {value} "set $name \$value"
                  }

       Note  that  a snit::macro is just a normal Tcl proc defined in the slave interpreter used to compile type
       and widget definitions; as a result, it has access to all the commands used to define types and widgets.

       Given this new macro, you can define a property in one line of code:

                  snit::type dog {
                      property mood happy
                  }

       Within a macro, the commands variable and proc refer  to  the  Snit  type-definition  commands,  not  the
       standard Tcl commands.  To get the standard Tcl commands, use _variable and _proc.

       Because  a  single slave interpreter is used for compiling all Snit types and widgets in the application,
       there's the possibility of macro name collisions.  If you're writing a reuseable package using Snit,  and
       you use some snit::macros, define them in your package namespace:

                  snit::macro mypkg::property {name initValue} { ... }

                  snit::type dog {
                      mypkg::property mood happy
                  }

       This leaves the global namespace open for application authors.

   VALIDATION TYPES
       A  validation  type  is  an  object  that  can  be used to validate Tcl values of a particular kind.  For
       example, snit::integer is used to validate that a Tcl value is an integer.

       Every validation type has a validate method which is used to do the validation. This method must  take  a
       single  argument, the value to be validated; further, it must do nothing if the value is valid, but throw
       an error if the value is invalid:

                  snit::integer validate 5     ;# Does nothing
                  snit::integer validate 5.0   ;# Throws an error (not an integer!)

       The validate method will always return the validated value on success, and throw the  -errorcode  INVALID
       on error.

       Snit  defines  a  family  of validation types, all of which are implemented as snit::type's.  They can be
       used as is; in addition, their instances serve as parameterized subtypes.  For example, a probability  is
       a number between 0.0 and 1.0 inclusive:

                  snit::double probability -min 0.0 -max 1.0

       The  example  above  creates an instance of snit::double--a validation subtype--called probability, which
       can be used to validate probability values:

                  probability validate 0.5   ;# Does nothing
                  probability validate 7.9   ;# Throws an error

       Validation subtypes can be defined explicitly, as in the above example; when a  locally-defined  option's
       -type is specified, they may also be created on the fly:

                  snit::enum ::dog::breed -values {mutt retriever sheepdog}

                  snit::type dog {
                      # Define subtypes on the fly...
                      option -breed -type {
                          snit::enum -values {mutt retriever sheepdog}
                      }

                      # Or use predefined subtypes...
                      option -breed -type ::dog::breed
                  }

       Any  object  that  has  a  validate method with the semantics described above can be used as a validation
       type; see Defining Validation Types for information on how to define new ones.

       Snit defines the following validation types:

       snit::boolean validate ?value?

       snit::boolean name
              Validates Tcl boolean values: 1, 0, on, off, yes,  no,  true,  false.   It's  possible  to  define
              subtypes--that  is,  instances--of snit::boolean, but as it has no options there's no reason to do
              so.

       snit::double validate ?value?

       snit::double name ?option value...?
              Validates floating-point values.  Subtypes may be created with the following options:

              -min min
                     Specifies a floating-point minimum bound; a value is invalid if it is  strictly  less  than
                     min.

              -max max
                     Specifies a floating-point maximum bound; a value is invalid if it is strictly greater than
                     max.

       snit::enum validate ?value?

       snit::enum name ?option value...?
              Validates  that  a value comes from an enumerated list.  The base type is of little use by itself,
              as only subtypes actually have an enumerated list to validate against.  Subtypes  may  be  created
              with the following options:

              -values list
                     Specifies  a  list  of  valid values.  A value is valid if and only if it's included in the
                     list.

       snit::fpixels validate ?value?

       snit::fpixels name ?option value...?
              Tk programs only. Validates screen distances, in any of  the  forms  accepted  by  winfo  fpixels.
              Subtypes may be created with the following options:

              -min min
                     Specifies  a  minimum bound; a value is invalid if it is strictly less than min.  The bound
                     may be expressed in any of the forms accepted by winfo fpixels.

              -max max
                     Specifies a maximum bound; a value is invalid if it is  strictly  greater  than  max.   The
                     bound may be expressed in any of the forms accepted by winfo fpixels.

       snit::integer validate ?value?

       snit::integer name ?option value...?
              Validates integer values.  Subtypes may be created with the following options:

              -min min
                     Specifies an integer minimum bound; a value is invalid if it is strictly less than min.

              -max max
                     Specifies an integer maximum bound; a value is invalid if it is strictly greater than max.

       snit::listtype validate ?value?

       snit::listtype name ?option value...?
              Validates Tcl lists. Subtypes may be created with the following options:

              -minlen min
                     Specifies  a  minimum  list length; the value is invalid if it has fewer than min elements.
                     Defaults to 0.

              -maxlen max
                     Specifies a maximum list length; the value is invalid if it more than max elements.

              -type type
                     Specifies the type of the list elements; type must be the name  of  a  validation  type  or
                     subtype.  In the following example, the value of -numbers must be a list of integers.

                         option -numbers -type {snit::listtype -type snit::integer}

                     Note that this option doesn't support defining new validation subtypes on the fly; that is,
                     the following code will not work (yet, anyway):

                         option -numbers -type {
                             snit::listtype -type {snit::integer -min 5}
                         }

                     Instead, define the subtype explicitly:

                         snit::integer gt4 -min 5

                         snit::type mytype {
                             option -numbers -type {snit::listtype -type gt4}
                         }

       snit::pixels validate ?value?

       snit::pixels name ?option value...?
              Tk  programs  only.  Validates  screen  distances,  in  any of the forms accepted by winfo pixels.
              Subtypes may be created with the following options:

              -min min
                     Specifies a minimum bound; a value is invalid if it is strictly less than min.   The  bound
                     may be expressed in any of the forms accepted by winfo pixels.

              -max max
                     Specifies  a  maximum  bound;  a  value is invalid if it is strictly greater than max.  The
                     bound may be expressed in any of the forms accepted by winfo pixels.

       snit::stringtype validate ?value?

       snit::stringtype name ?option value...?
              Validates Tcl strings. The base type is of little use by itself, since very Tcl value  is  also  a
              valid string.  Subtypes may be created with the following options:

              -minlen min
                     Specifies  a  minimum  string  length;  the  value  is  invalid  if  it  has fewer than min
                     characters.  Defaults to 0.

              -maxlen max
                     Specifies a maximum string length; the value is invalid if it has more than max characters.

              -glob pattern
                     Specifies a string match pattern; the value is invalid if it doesn't match the pattern.

              -regexp regexp
                     Specifies a regular expression; the value is  invalid  if  it  doesn't  match  the  regular
                     expression.

              -nocase flag
                     By  default, both -glob and -regexp matches are case-sensitive.  If -nocase is set to true,
                     then both -glob and -regexp matches are case-insensitive.

       snit::window validate ?value?

       snit::window name
              Tk programs only.  Validates Tk window names.  The value must cause winfo exists to  return  true;
              otherwise,  the  value  is  invalid.   It's  possible  to  define subtypes--that is, instances--of
              snit::window, but as it has no options at present there's no reason to do so.

   DEFINING VALIDATION TYPES
       There are three ways to define a new validation type: as a subtype of one of Snit's validation types,  as
       a  validation  type  command,  and  as  a full-fledged validation type similar to those provided by Snit.
       Defining subtypes of Snit's validation types is described above, under Validation Types.

       The next simplest way to create a new validation type is as a validation type command.  A validation type
       is simply an object that has a validate method; the validate method must  take  one  argument,  a  value,
       return  the  value  if  it  is valid, and throw an error with -errorcode INVALID if the value is invalid.
       This can be done with a simple proc.  For example,  the  snit::boolean  validate  type  could  have  been
       implemented like this:

                  proc ::snit::boolean {"validate" value} {
                      if {![string is boolean -strict $value]} {
                          return -code error -errorcode INVALID  "invalid boolean \"$value\", should be one of: 1, 0, ..."
                      }

                      return $value
                  }

       A  validation type defined in this way cannot be subtyped, of course; but for many applications this will
       be sufficient.

       Finally, one can define a full-fledged, subtype-able validation type as a snit::type.  Here's a  skeleton
       to get you started:

                  snit::type myinteger {
                      # First, define any options you'd like to use to define
                      # subtypes.  Give them defaults such that they won't take
                      # effect if they aren't used, and marked them "read-only".
                      # After all, you shouldn't be changing their values after
                      # a subtype is defined.
                      #
                      # For example:

                      option -min -default "" -readonly 1
                      option -max -default "" -readonly 1

                      # Next, define a "validate" type method which should do the
                      # validation in the basic case.  This will allow the
                      # type command to be used as a validation type.

                      typemethod validate {value} {
                          if {![string is integer -strict $value]} {
                              return -code error -errorcode INVALID  "invalid value \"$value\", expected integer"
                          }

                          return $value
                      }

                      # Next, the constructor should validate the subtype options,
                      # if any.  Since they are all readonly, we don't need to worry
                      # about validating the options on change.

                      constructor {args} {
                          # FIRST, get the options
                          $self configurelist $args

                          # NEXT, validate them.

                          # I'll leave this to your imagination.
                      }

                      # Next, define a "validate" instance method; its job is to
                      # validate values for subtypes.

                      method validate {value} {
                          # First, call the type method to do the basic validation.
                          $type validate $value

                          # Now we know it's a valid integer.

                          if {("" != $options(-min) && $value < $options(-min))  ||
                              ("" != $options(-max) && $value > $options(-max))} {
                              # It's out of range; format a detailed message about
                              # the error, and throw it.

                              set msg "...."

                              return -code error -errorcode INVALID $msg
                          }

                          # Otherwise, if it's valid just return it.
                          return $valid
                      }
                  }

       And now you have a type that can be subtyped.

       The file "validate.tcl" in the Snit distribution defines all of Snit's validation types; you can find the
       complete  implementation  for  snit::integer  and  the other types there, to use as examples for your own
       types.

CAVEATS

       If you have problems, find bugs, or new ideas you are hereby cordially invited to submit a report of your
       problem, bug, or idea as explained in the section Bugs, Ideas, Feedback below.

       Additionally, you might wish to join  the  Snit  mailing  list;  see  http://www.wjduquette.com/snit  for
       details.

       One  particular  area  to  watch  is  using  snit::widgetadaptor  to  adapt  megawidgets created by other
       megawidget packages; correct widget destruction depends on the order  of  the  <Destroy>  bindings.   The
       wisest course is simply not to do this.

KNOWN BUGS

       •      Error  stack  traces  returned  by  Snit 1.x are extremely ugly and typically contain far too much
              information about Snit internals.  The error messages are much improved in Snit 2.2.

       •      Also see the Project Trackers as explained in the section Bugs, Ideas, Feedback below.

HISTORY

       During the course of developing Notebook (See http://www.wjduquette.com/notebook), my Tcl-based  personal
       notebook application, I found I was writing it as a collection of objects.  I wasn't using any particular
       object-oriented framework; I was just writing objects in pure Tcl following the guidelines in my Guide to
       Object  Commands  (see  http://www.wjduquette.com/tcl/objects.html),  along  with  a few other tricks I'd
       picked up since.  And though it was working well, it quickly became tiresome because  of  the  amount  of
       boilerplate code associated with each new object type.

       So  that  was  one thing--tedium is a powerful motivator.  But the other thing I noticed is that I wasn't
       using inheritance at all, and I wasn't missing it.  Instead, I was using delegation: objects that created
       other objects and delegated methods to them.

       And I said to myself, "This is getting tedious...there has got to be a better way."  And  one  afternoon,
       on  a  whim,  I  started  working  on  Snit, an object system that works the way Tcl works.  Snit doesn't
       support inheritance, but it's great at delegation, and it makes creating megawidgets easy.

       If you have any comments  or  suggestions  (or  bug  reports!)  don't  hesitate  to  send  me  e-mail  at
       will@wjduquette.com.   In  addition,  there's  a Snit mailing list; you can find out more about it at the
       Snit home page (see http://www.wjduquette.com/snit).

CREDITS

       Snit has been designed and implemented from the very beginning by William  H.  Duquette.   However,  much
       credit  belongs to the following people for using Snit and providing me with valuable feedback: Rolf Ade,
       Colin McCormack, Jose Nazario, Jeff  Godfrey,  Maurice  Diamanti,  Egon  Pasztor,  David  S.  Cargo,  Tom
       Krehbiel,  Michael  Cleverly,  Andreas  Kupries, Marty Backe, Andy Goth, Jeff Hobbs, Brian Griffin, Donal
       Fellows, Miguel Sofer, Kenneth Green, and Anton Kovalenko.  If I've forgotten anyone, my  apologies;  let
       me know and I'll add your name to the list.

BUGS, IDEAS, FEEDBACK

       This  document,  and  the package it describes, will undoubtedly contain bugs and other problems.  Please
       report such in the category snit of the Tcllib Trackers  [http://core.tcl.tk/tcllib/reportlist].   Please
       also report any ideas for enhancements you may have for either package and/or documentation.

       When proposing code changes, please provide unified diffs, i.e the output of diff -u.

       Note  further  that  attachments  are strongly preferred over inlined patches. Attachments can be made by
       going to the Edit form of the ticket immediately after its creation, and then using the left-most  button
       in the secondary navigation bar.

KEYWORDS

       BWidget, C++, Incr Tcl, Snit, adaptors, class, mega widget, object, object oriented, type, widget, widget
       adaptors

CATEGORY

       Programming tools

COPYRIGHT

       Copyright (c) 2003-2009, by William H. Duquette

tcllib                                                2.3.2                                           snit(3tcl)