1snit(n) Snit's Not Incr Tcl, OO system snit(n)
2
3
4
5______________________________________________________________________________
6
8 snit - Snit's Not Incr Tcl
9
11 package require Tcl 8.5
12
13 package require snit ?2.3.2?
14
15 snit::type name definition
16
17 typevariable name ?-array? ?value?
18
19 typemethod name arglist body
20
21 typeconstructor body
22
23 variable name ?-array? ?value?
24
25 method name arglist body
26
27 option namespec ?defaultValue?
28
29 option namespec ?options...?
30
31 constructor arglist body
32
33 destructor body
34
35 proc name args body
36
37 delegate method name to comp ?as target?
38
39 delegate method name ?to comp? using pattern
40
41 delegate method * ?to comp? ?using pattern? ?except exceptions?
42
43 delegate option namespec to comp
44
45 delegate option namespec to comp as target
46
47 delegate option * to comp
48
49 delegate option * to comp except exceptions
50
51 component comp ?-public method? ?-inherit flag?
52
53 delegate typemethod name to comp ?as target?
54
55 delegate typemethod name ?to comp? using pattern
56
57 delegate typemethod * ?to comp? ?using pattern? ?except exceptions?
58
59 typecomponent comp ?-public typemethod? ?-inherit flag?
60
61 pragma ?options...?
62
63 expose comp
64
65 expose comp as method
66
67 onconfigure name arglist body
68
69 oncget name body
70
71 snit::widget name definition
72
73 widgetclass name
74
75 hulltype type
76
77 snit::widgetadaptor name definition
78
79 snit::typemethod type name arglist body
80
81 snit::method type name arglist body
82
83 snit::macro name arglist body
84
85 snit::compile which type body
86
87 $type typemethod args...
88
89 $type create name ?option value ...?
90
91 $type info typevars ?pattern?
92
93 $type info typemethods ?pattern?
94
95 $type info args method
96
97 $type info body method
98
99 $type info default method aname varname
100
101 $type info instances ?pattern?
102
103 $type destroy
104
105 $object method args...
106
107 $object configure ?option? ?value? ...
108
109 $object configurelist optionlist
110
111 $object cget option
112
113 $object destroy
114
115 $object info type
116
117 $object info vars ?pattern?
118
119 $object info typevars ?pattern?
120
121 $object info typemethods ?pattern?
122
123 $object info options ?pattern?
124
125 $object info methods ?pattern?
126
127 $object info args method
128
129 $object info body method
130
131 $object info default method aname varname
132
133 mymethod name ?args...?
134
135 mytypemethod name ?args...?
136
137 myproc name ?args...?
138
139 myvar name
140
141 mytypevar name
142
143 from argvName option ?defvalue?
144
145 install compName using objType objName args...
146
147 installhull using widgetType args...
148
149 installhull name
150
151 variable name
152
153 typevariable name
154
155 varname name
156
157 typevarname name
158
159 codename name
160
161 snit::boolean validate ?value?
162
163 snit::boolean name
164
165 snit::double validate ?value?
166
167 snit::double name ?option value...?
168
169 snit::enum validate ?value?
170
171 snit::enum name ?option value...?
172
173 snit::fpixels validate ?value?
174
175 snit::fpixels name ?option value...?
176
177 snit::integer validate ?value?
178
179 snit::integer name ?option value...?
180
181 snit::listtype validate ?value?
182
183 snit::listtype name ?option value...?
184
185 snit::pixels validate ?value?
186
187 snit::pixels name ?option value...?
188
189 snit::stringtype validate ?value?
190
191 snit::stringtype name ?option value...?
192
193 snit::window validate ?value?
194
195 snit::window name
196
197______________________________________________________________________________
198
200 Snit is a pure Tcl object and megawidget system. It's unique among Tcl
201 object systems in that it's based not on inheritance but on delegation.
202 Object systems based on inheritance only allow you to inherit from
203 classes defined using the same system, which is limiting. In Tcl, an
204 object is anything that acts like an object; it shouldn't matter how
205 the object was implemented. Snit is intended to help you build appli‐
206 cations out of the materials at hand; thus, Snit is designed to be able
207 to incorporate and build on any object, whether it's a hand-coded
208 object, a Tk widget, an Incr Tcl object, a BWidget or almost anything
209 else.
210
211 This man page is intended to be a reference only; see the accompanying
212 snitfaq for a gentler, more tutorial introduction to Snit concepts.
213
215 This man page covers both Snit 2.2 and Snit 1.3. The primary differ‐
216 ence between the two versions is simply that Snit 2.2 contains speed
217 optimizations based on new features of Tcl 8.5; Snit 1.3 supports all
218 of Tcl 8.3, 8.4 and Tcl 8.5. There are a few minor inconsistencies;
219 they are flagged in the body of the man page with the label "Snit 1.x
220 Incompatibility"; they are also discussed in the snitfaq.
221
223 TYPE AND WIDGET DEFINITIONS
224 Snit provides the following commands for defining new types:
225
226 snit::type name definition
227 Defines a new abstract data type called name. If name is not a
228 fully qualified command name, it is assumed to be a name in the
229 namespace in which the snit::type command was called (usually
230 the global namespace). It returns the fully qualified name of
231 the new type.
232
233 The type name is then a command that is used to create objects
234 of the new type, along with other activities.
235
236 The snit::type definition block is a script that may contain the
237 following definitions:
238
239 typevariable name ?-array? ?value?
240 Defines a type variable with the specified name, and
241 optionally the specified value. Type variables are
242 shared by all instances of the type. If the -array
243 option is included, then value should be a dictionary; it
244 will be assigned to the variable using array set.
245
246 typemethod name arglist body
247 Defines a type method, a subcommand of the new type com‐
248 mand, with the specified name, argument list, and body.
249 The arglist is a normal Tcl argument list and may contain
250 default arguments and the args argument; however, it may
251 not contain the argument names type, self, selfns, or
252 win.
253
254 The variable type is automatically defined in the body to
255 the type's fully-qualified name. In addition, type vari‐
256 ables are automatically visible in the body of every type
257 method.
258
259 If the name consists of two or more tokens, Snit handles
260 it specially:
261
262 typemethod {a b} {arg} { puts "Got $arg" }
263
264
265 This statement implicitly defines a type method called a
266 which has a subcommand b. b is called like this:
267
268 $type a b "Hello, world!"
269
270
271 a may have any number of subcommands. This makes it pos‐
272 sible to define a hierarchical command structure; see
273 method, below, for more examples.
274
275 Type methods can call commands from the namespace in
276 which the type is defined without importing them, e.g.,
277 if the type name is ::parentns::typename, then the type's
278 type methods can call ::parentns::someproc just as some‐
279 proc. Snit 1.x Incompatibility: This does not work in
280 Snit 1.x, as it depends on namespace path, a new command
281 in Tcl 8.5.
282
283 Snit 1.x Incompatibility: In Snit 1.x, the following fol‐
284 lowing two calls to this type method are equivalent:
285
286 $type a b "Hello, world!"
287 $type {a b} "Hello, world!"
288
289
290 In Snit 2.2, the second form is invalid.
291
292 typeconstructor body
293 The type constructor's body is executed once when the
294 type is first defined; it is typically used to initialize
295 array-valued type variables and to add entries to The Tk
296 Option Database.
297
298 The variable type is automatically defined in the body,
299 and contains the type's fully-qualified name. In addi‐
300 tion, type variables are automatically visible in the
301 body of the type constructor.
302
303 A type may define at most one type constructor.
304
305 The type constructor can call commands from the namespace
306 in which the type is defined without importing them,
307 e.g., if the type name is ::parentns::typename, then the
308 type constructor can call ::parentns::someproc just as
309 someproc. Snit 1.x Incompatibility: This does not work
310 in Snit 1.x, as it depends on namespace path, a new com‐
311 mand in Tcl 8.5.
312
313 variable name ?-array? ?value?
314 Defines an instance variable, a private variable associ‐
315 ated with each instance of this type, and optionally its
316 initial value. If the -array option is included, then
317 value should be a dictionary; it will be assigned to the
318 variable using array set.
319
320 method name arglist body
321 Defines an instance method, a subcommand of each instance
322 of this type, with the specified name, argument list and
323 body. The arglist is a normal Tcl argument list and may
324 contain default arguments and the args argument.
325
326 The method is implicitly passed the following arguments
327 as well: type, which contains the fully-qualified type
328 name; self, which contains the current instance command
329 name; selfns, which contains the name of the instance's
330 private namespace; and win, which contains the original
331 instance name. Consequently, the arglist may not contain
332 the argument names type, self, selfns, or win.
333
334 An instance method defined in this way is said to be
335 locally defined.
336
337 Type and instance variables are automatically visible in
338 all instance methods. If the type has locally defined
339 options, the options array is also visible.
340
341 If the name consists of two or more tokens, Snit handles
342 it specially:
343
344 method {a b} {} { ... }
345
346
347 This statement implicitly defines a method called a which
348 has a subcommand b. b is called like this:
349
350 $self a b "Hello, world!"
351
352
353 a may have any number of subcommands. This makes it pos‐
354 sible to define a hierarchical command structure:
355
356 % snit::type dog {
357 method {tail wag} {} {return "Wag, wag"}
358 method {tail droop} {} {return "Droop, droop"}
359 }
360 ::dog
361 % dog spot
362 ::spot
363 % spot tail wag
364 Wag, wag
365 % spot tail droop
366 Droop, droop
367 %
368
369
370 What we've done is implicitly defined a "tail" method
371 with subcommands "wag" and "droop". Consequently, it's
372 an error to define "tail" explicitly.
373
374 Methods can call commands from the namespace in which the
375 type is defined without importing them, e.g., if the type
376 name is ::parentns::typename, then the type's methods can
377 call ::parentns::someproc just as someproc. Snit 1.x
378 Incompatibility: This does not work in Snit 1.x, as it
379 depends on namespace path, a new command in Tcl 8.5.
380
381 Snit 1.x Incompatibility: In Snit 1.x, the following fol‐
382 lowing two calls to this method are equivalent:
383
384 $self a b "Hello, world!"
385 $self {a b} "Hello, world!"
386
387
388 In Snit 2.2, the second form is invalid.
389
390 option namespec ?defaultValue?
391
392 option namespec ?options...?
393 Defines an option for instances of this type, and option‐
394 ally gives it an initial value. The initial value
395 defaults to the empty string if no defaultValue is speci‐
396 fied.
397
398 An option defined in this way is said to be locally
399 defined.
400
401 The namespec is a list defining the option's name,
402 resource name, and class name, e.g.:
403
404 option {-font font Font} {Courier 12}
405
406
407 The option name must begin with a hyphen, and must not
408 contain any upper case letters. The resource name and
409 class name are optional; if not specified, the resource
410 name defaults to the option name, minus the hyphen, and
411 the class name defaults to the resource name with the
412 first letter capitalized. Thus, the following statement
413 is equivalent to the previous example:
414
415 option -font {Courier 12}
416
417
418 See The Tk Option Database for more information about
419 resource and class names.
420
421 Options are normally set and retrieved using the standard
422 instance methods configure and cget; within instance code
423 (method bodies, etc.), option values are available
424 through the options array:
425
426 set myfont $options(-font)
427
428
429 If the type defines any option handlers (e.g., -config‐
430 uremethod), then it should probably use configure and
431 cget to access its options to avoid subtle errors.
432
433 The option statement may include the following options:
434
435 -default defvalue
436 Defines the option's default value; the option's
437 default value will be "" otherwise.
438
439 -readonly flag
440 The flag can be any Boolean value recognized by
441 Tcl. If flag is true, then the option is read-
442 only--it can only be set using configure or con‐
443 figurelist at creation time, i.e., in the type's
444 constructor.
445
446 -type type
447 Every locally-defined option may define its vali‐
448 dation type, which may be either the name of a
449 validation type or a specification for a valida‐
450 tion subtype
451
452 For example, an option may declare that its value
453 must be an integer by specifying snit::integer as
454 its validation type:
455
456 option -number -type snit::integer
457
458
459 It may also declare that its value is an integer
460 between 1 and 10 by specifying a validation sub‐
461 type:
462
463 option -number -type {snit::integer -min 1 -max 10}
464
465
466 If a validation type or subtype is defined for an
467 option, then it will be used to validate the
468 option's value whenever it is changed by the
469 object's configure or configurelist methods. In
470 addition, all such options will have their values
471 validated automatically immediately after the con‐
472 structor executes.
473
474 Snit defines a family of validation types and sub‐
475 types, and it's quite simple to define new ones.
476 See Validation Types for the complete list, and
477 Defining Validation Types for an explanation of
478 how to define your own.
479
480 -cgetmethod methodName
481 Every locally-defined option may define a -cget‐
482 method; it is called when the option's value is
483 retrieved using the cget method. Whatever the
484 method's body returns will be the return value of
485 the call to cget.
486
487 The named method must take one argument, the
488 option name. For example, this code is equivalent
489 to (though slower than) Snit's default handling of
490 cget:
491
492 option -font -cgetmethod GetOption
493 method GetOption {option} {
494 return $options($option)
495 }
496
497
498 Note that it's possible for any number of options
499 to share a -cgetmethod.
500
501 -configuremethod methodName
502 Every locally-defined option may define a -config‐
503 uremethod; it is called when the option's value is
504 set using the configure or configurelist methods.
505 It is the named method's responsibility to save
506 the option's value; in other words, the value will
507 not be saved to the options() array unless the
508 method saves it there.
509
510 The named method must take two arguments, the
511 option name and its new value. For example, this
512 code is equivalent to (though slower than) Snit's
513 default handling of configure:
514
515 option -font -configuremethod SetOption
516 method SetOption {option value} {
517 set options($option) $value
518 }
519
520
521 Note that it's possible for any number of options
522 to share a single -configuremethod.
523
524 -validatemethod methodName
525 Every locally-defined option may define a -vali‐
526 datemethod; it is called when the option's value
527 is set using the configure or configurelist meth‐
528 ods, just before the -configuremethod (if any).
529 It is the named method's responsibility to vali‐
530 date the option's new value, and to throw an error
531 if the value is invalid.
532
533 The named method must take two arguments, the
534 option name and its new value. For example, this
535 code verifies that -flag's value is a valid Bool‐
536 ean value:
537
538 option -font -validatemethod CheckBoolean
539 method CheckBoolean {option value} {
540 if {![string is boolean -strict $value]} {
541 error "option $option must have a boolean value."
542 }
543 }
544
545
546 Note that it's possible for any number of options
547 to share a single -validatemethod.
548
549 constructor arglist body
550 The constructor definition specifies a body of code to be
551 executed when a new instance is created. The arglist is
552 a normal Tcl argument list and may contain default argu‐
553 ments and the args argument.
554
555 As with methods, the arguments type, self, selfns, and
556 win are defined implicitly, and all type and instance
557 variables are automatically visible in its body.
558
559 If the definition doesn't explicitly define the construc‐
560 tor, Snit defines one implicitly. If the type declares
561 at least one option (whether locally or by delegation),
562 the default constructor will be defined as follows:
563
564 constructor {args} {
565 $self configurelist $args
566 }
567
568
569 For standard Tk widget behavior, the argument list should
570 be the single name args, as shown.
571
572 If the definition defines neither a constructor nor any
573 options, the default constructor is defined as follows:
574
575 constructor {} {}
576
577
578 As with methods, the constructor can call commands from
579 the namespace in which the type is defined without
580 importing them, e.g., if the type name is ::par‐
581 entns::typename, then the constructor can call ::par‐
582 entns::someproc just as someproc. Snit 1.x Incompatibil‐
583 ity: This does not work in Snit 1.x, as it depends on
584 namespace path, a new command in Tcl 8.5.
585
586 destructor body
587 The destructor is used to code any actions that must take
588 place when an instance of the type is destroyed: typi‐
589 cally, the destruction of anything created in the con‐
590 structor.
591
592 The destructor takes no explicit arguments; as with meth‐
593 ods, the arguments type, self, selfns, and win, are
594 defined implicitly, and all type and instance variables
595 are automatically visible in its body. As with methods,
596 the destructor can call commands from the namespace in
597 which the type is defined without importing them, e.g.,
598 if the type name is ::parentns::typename, then the
599 destructor can call ::parentns::someproc just as some‐
600 proc. Snit 1.x Incompatibility: This does not work in
601 Snit 1.x, as it depends on namespace path, a new command
602 in Tcl 8.5.
603
604 proc name args body
605 Defines a new Tcl procedure in the type's namespace.
606
607 The defined proc differs from a normal Tcl proc in that
608 all type variables are automatically visible. The proc
609 can access instance variables as well, provided that it
610 is passed selfns (with precisely that name) as one of its
611 arguments.
612
613 Although they are not implicitly defined for procs, the
614 argument names type, self, and win should be avoided.
615
616 As with methods and typemethods, procs can call commands
617 from the namespace in which the type is defined without
618 importing them, e.g., if the type name is ::par‐
619 entns::typename, then the proc can call ::parentns::some‐
620 proc just as someproc. Snit 1.x Incompatibility: This
621 does not work in Snit 1.x, as it depends on namespace
622 path, a new command in Tcl 8.5.
623
624 delegate method name to comp ?as target?
625 Delegates method name to component comp. That is, when
626 method name is called on an instance of this type, the
627 method and its arguments will be passed to the named com‐
628 ponent's command instead. That is, the following state‐
629 ment
630
631 delegate method wag to tail
632
633
634 is roughly equivalent to this explicitly defined method:
635
636 method wag {args} {
637 uplevel $tail wag $args
638 }
639
640
641 As with methods, the name may have multiple tokens; in
642 this case, the last token of the name is assumed to be
643 the name of the component's method.
644
645 The optional as clause allows you to specify the dele‐
646 gated method name and possibly add some arguments:
647
648 delegate method wagtail to tail as "wag briskly"
649
650
651 A method cannot be both locally defined and delegated.
652
653 Note: All forms of delegate method can delegate to both instance
654 components and type components.
655
656 delegate method name ?to comp? using pattern
657 In this form of the delegate statement, the using clause
658 is used to specify the precise form of the command to
659 which method name name is delegated. In this form, the
660 to clause is optional, since the chosen command might not
661 involve any particular component.
662
663 The value of the using clause is a list that may contain
664 any or all of the following substitution codes; these
665 codes are substituted with the described value to build
666 the delegated command prefix. Note that the following
667 two statements are equivalent:
668
669 delegate method wag to tail
670 delegate method wag to tail using "%c %m"
671
672
673 Each element of the list becomes a single element of the
674 delegated command--it is never reparsed as a string.
675
676 Substitutions:
677
678 %% This is replaced with a single "%". Thus, to pass
679 the string "%c" to the command as an argument,
680 you'd write "%%c".
681
682 %c This is replaced with the named component's com‐
683 mand.
684
685 %m This is replaced with the final token of the
686 method name; if the method name has one token,
687 this is identical to %M.
688
689 %M This is replaced by the method name; if the name
690 consists of multiple tokens, they are joined by
691 space characters.
692
693 %j This is replaced by the method name; if the name
694 consists of multiple tokens, they are joined by
695 underscores ("_").
696
697 %t This is replaced with the fully qualified type
698 name.
699
700 %n This is replaced with the name of the instance's
701 private namespace.
702
703 %s This is replaced with the name of the instance
704 command.
705
706 %w This is replaced with the original name of the
707 instance command; for Snit widgets and widget
708 adaptors, it will be the Tk window name. It
709 remains constant, even if the instance command is
710 renamed.
711
712 delegate method * ?to comp? ?using pattern? ?except exceptions?
713 The form delegate method * delegates all unknown method
714 names to the specified component. The except clause can
715 be used to specify a list of exceptions, i.e., method
716 names that will not be so delegated. The using clause is
717 defined as given above. In this form, the statement must
718 contain the to clause, the using clause, or both.
719
720 In fact, the "*" can be a list of two or more tokens
721 whose last element is "*", as in the following example:
722
723 delegate method {tail *} to tail
724
725
726 This implicitly defines the method tail whose subcommands
727 will be delegated to the tail component.
728
729 delegate option namespec to comp
730
731 delegate option namespec to comp as target
732
733 delegate option * to comp
734
735 delegate option * to comp except exceptions
736 Defines a delegated option; the namespec is defined as
737 for the option statement. When the configure, config‐
738 urelist, or cget instance method is used to set or
739 retrieve the option's value, the equivalent configure or
740 cget command will be applied to the component as though
741 the option was defined with the following -config‐
742 uremethod and -cgetmethod:
743
744 method ConfigureMethod {option value} {
745 $comp configure $option $value
746 }
747
748 method CgetMethod {option} {
749 return [$comp cget $option]
750 }
751
752
753 Note that delegated options never appear in the options
754 array.
755
756 If the as clause is specified, then the target option
757 name is used in place of name.
758
759 The form delegate option * delegates all unknown options
760 to the specified component. The except clause can be
761 used to specify a list of exceptions, i.e., option names
762 that will not be so delegated.
763
764 Warning: options can only be delegated to a component if
765 it supports the configure and cget instance methods.
766
767 An option cannot be both locally defined and delegated.
768 TBD: Continue from here.
769
770 component comp ?-public method? ?-inherit flag?
771 Explicitly declares a component called comp, and automat‐
772 ically defines the component's instance variable.
773
774 If the -public option is specified, then the option is
775 made public by defining a method whose subcommands are
776 delegated to the component e.g., specifying -public
777 mycomp is equivalent to the following:
778
779 component mycomp
780 delegate method {mymethod *} to mycomp
781
782
783 If the -inherit option is specified, then flag must be a
784 Boolean value; if flag is true then all unknown methods
785 and options will be delegated to this component. The
786 name -inherit implies that instances of this new type
787 inherit, in a sense, the methods and options of the com‐
788 ponent. That is, -inherit yes is equivalent to:
789
790 component mycomp
791 delegate option * to mycomp
792 delegate method * to mycomp
793
794
795 delegate typemethod name to comp ?as target?
796 Delegates type method name to type component comp. That
797 is, when type method name is called on this type, the
798 type method and its arguments will be passed to the named
799 type component's command instead. That is, the following
800 statement
801
802 delegate typemethod lostdogs to pound
803
804
805 is roughly equivalent to this explicitly defined method:
806
807 typemethod lostdogs {args} {
808 uplevel $pound lostdogs $args
809 }
810
811
812 As with type methods, the name may have multiple tokens;
813 in this case, the last token of the name is assumed to be
814 the name of the component's method.
815
816 The optional as clause allows you to specify the dele‐
817 gated method name and possibly add some arguments:
818
819 delegate typemethod lostdogs to pound as "get lostdogs"
820
821
822 A type method cannot be both locally defined and delegated.
823
824 delegate typemethod name ?to comp? using pattern
825 In this form of the delegate statement, the using clause
826 is used to specify the precise form of the command to
827 which type method name name is delegated. In this form,
828 the to clause is optional, since the chosen command might
829 not involve any particular type component.
830
831 The value of the using clause is a list that may contain
832 any or all of the following substitution codes; these
833 codes are substituted with the described value to build
834 the delegated command prefix. Note that the following
835 two statements are equivalent:
836
837 delegate typemethod lostdogs to pound
838 delegate typemethod lostdogs to pound using "%c %m"
839
840
841 Each element of the list becomes a single element of the
842 delegated command--it is never reparsed as a string.
843
844 Substitutions:
845
846 %% This is replaced with a single "%". Thus, to pass
847 the string "%c" to the command as an argument,
848 you'd write "%%c".
849
850 %c This is replaced with the named type component's
851 command.
852
853 %m This is replaced with the final token of the type
854 method name; if the type method name has one
855 token, this is identical to %M.
856
857 %M This is replaced by the type method name; if the
858 name consists of multiple tokens, they are joined
859 by space characters.
860
861 %j This is replaced by the type method name; if the
862 name consists of multiple tokens, they are joined
863 by underscores ("_").
864
865 %t This is replaced with the fully qualified type
866 name.
867
868 delegate typemethod * ?to comp? ?using pattern? ?except excep‐
869 tions?
870 The form delegate typemethod * delegates all unknown type
871 method names to the specified type component. The except
872 clause can be used to specify a list of exceptions, i.e.,
873 type method names that will not be so delegated. The
874 using clause is defined as given above. In this form,
875 the statement must contain the to clause, the using
876 clause, or both.
877
878 Note: By default, Snit interprets $type foo, where foo is
879 not a defined type method, as equivalent to $type create
880 foo, where foo is the name of a new instance of the type.
881 If you use delegate typemethod *, then the create type
882 method must always be used explicitly.
883
884 The "*" can be a list of two or more tokens whose last
885 element is "*", as in the following example:
886
887 delegate typemethod {tail *} to tail
888
889
890 This implicitly defines the type method tail whose sub‐
891 commands will be delegated to the tail type component.
892
893 typecomponent comp ?-public typemethod? ?-inherit flag?
894 Explicitly declares a type component called comp, and
895 automatically defines the component's type variable. A
896 type component is an arbitrary command to which type
897 methods and instance methods can be delegated; the com‐
898 mand's name is stored in a type variable.
899
900 If the -public option is specified, then the type compo‐
901 nent is made public by defining a typemethod whose sub‐
902 commands are delegated to the type component, e.g., spec‐
903 ifying -public mytypemethod is equivalent to the follow‐
904 ing:
905
906 typecomponent mycomp
907 delegate typemethod {mytypemethod *} to mycomp
908
909
910 If the -inherit option is specified, then flag must be a
911 Boolean value; if flag is true then all unknown type
912 methods will be delegated to this type component. (See
913 the note on "delegate typemethod *", above.) The name
914 -inherit implies that this type inherits, in a sense, the
915 behavior of the type component. That is, -inherit yes is
916 equivalent to:
917
918 typecomponent mycomp
919 delegate typemethod * to mycomp
920
921
922 pragma ?options...?
923 The pragma statement provides control over how Snit gen‐
924 erates a type. It takes the following options; in each
925 case, flag must be a Boolean value recognized by Tcl,
926 e.g., 0, 1, yes, no, and so on.
927
928 By setting the -hastypeinfo, -hastypedestroy, and -hasin‐
929 stances pragmas to false and defining appropriate type
930 methods, you can create an ensemble command without any
931 extraneous behavior.
932
933 -canreplace flag
934 If false (the default) Snit will not create an
935 instance of a snit::type that has the same name as
936 an existing command; this prevents subtle errors.
937 Setting this pragma to true restores the behavior
938 of Snit V0.93 and earlier versions.
939
940 -hastypeinfo flag
941 If true (the default), the generated type will
942 have a type method called info that is used for
943 type introspection; the info type method is docu‐
944 mented below. If false, it will not.
945
946 -hastypedestroy flag
947 If true (the default), the generated type will
948 have a type method called destroy that is used to
949 destroy the type and all of its instances. The
950 destroy type method is documented below. If
951 false, it will not.
952
953 -hastypemethods flag
954 If true (the default), the generated type's type
955 command will have subcommands (type methods) as
956 usual. If false, the type command will serve only
957 to create instances of the type; the first argu‐
958 ment is the instance name.
959
960 This pragma and -hasinstances cannot both be set
961 false.
962
963 -hasinstances flag
964 If true (the default), the generated type will
965 have a type method called create that is used to
966 create instances of the type, along with a variety
967 of instance-related features. If false, it will
968 not.
969
970 This pragma and -hastypemethods cannot both be set
971 false.
972
973 -hasinfo flag
974 If true (the default), instances of the generated
975 type will have an instance method called info that
976 is used for instance introspection; the info
977 method is documented below. If false, it will
978 not.
979
980 -simpledispatch flag
981 This pragma is intended to make simple, heavily-
982 used abstract data types (e.g., stacks and queues)
983 more efficient.
984
985 If false (the default), instance methods are dis‐
986 patched normally. If true, a faster dispatching
987 scheme is used instead. The speed comes at a
988 price; with -simpledispatch yes you get the fol‐
989 lowing limitations:
990
991 · Methods cannot be delegated.
992
993 · uplevel and upvar do not work as expected:
994 the caller's scope is two levels up rather
995 than one.
996
997 · The option-handling methods (cget, config‐
998 ure, and configurelist) are very slightly
999 slower.
1000
1001 expose comp
1002
1003 expose comp as method
1004 Deprecated. To expose component comp publicly, use com‐
1005 ponent's -public option.
1006
1007 onconfigure name arglist body
1008 Deprecated. Define option's -configuremethod option
1009 instead.
1010
1011 As of version 0.95, the following definitions,
1012
1013 option -myoption
1014 onconfigure -myoption {value} {
1015 # Code to save the option's value
1016 }
1017
1018
1019 are implemented as follows:
1020
1021 option -myoption -configuremethod _configure-myoption
1022 method _configure-myoption {_option value} {
1023 # Code to save the option's value
1024 }
1025
1026
1027 oncget name body
1028 Deprecated. Define option's -cgetmethod option instead.
1029
1030 As of version 0.95, the following definitions,
1031
1032 option -myoption
1033 oncget -myoption {
1034 # Code to return the option's value
1035 }
1036
1037
1038 are implemented as follows:
1039
1040 option -myoption -cgetmethod _cget-myoption
1041 method _cget-myoption {_option} {
1042 # Code to return the option's value
1043 }
1044
1045
1046 snit::widget name definition
1047 This command defines a Snit megawidget type with the specified
1048 name. The definition is defined as for snit::type. A
1049 snit::widget differs from a snit::type in these ways:
1050
1051 · Every instance of a snit::widget has an automatically-
1052 created component called hull, which is normally a Tk
1053 frame widget. Other widgets created as part of the
1054 megawidget will be created within this widget.
1055
1056 The hull component is initially created with the
1057 requested widget name; then Snit does some magic, renam‐
1058 ing the hull component and installing its own instance
1059 command in its place. The hull component's new name is
1060 saved in an instance variable called hull.
1061
1062 · The name of an instance must be valid Tk window name, and
1063 the parent window must exist.
1064
1065 A snit::widget definition can include any of statements allowed
1066 in a snit::type definition, and may also include the following:
1067
1068 widgetclass name
1069 Sets the snit::widget's widget class to name, overriding
1070 the default. See The Tk Option Database for more infor‐
1071 mation.
1072
1073 hulltype type
1074 Determines the kind of widget used as the snit::widget's
1075 hull. The type may be frame (the default), toplevel,
1076 labelframe; the qualified equivalents of these,
1077 tk::frame, tk::toplevel, and tk::labelframe; or, if
1078 available, the equivalent Tile widgets: ttk::frame,
1079 ttk::toplevel, and ttk::labelframe. In practice, any
1080 widget that supports the -class option can be used as a
1081 hull widget by lappend'ing its name to the variable
1082 snit::hulltypes.
1083
1084 snit::widgetadaptor name definition
1085 This command defines a Snit megawidget type with the specified
1086 name. It differs from snit::widget in that the instance's hull
1087 component is not created automatically, but is created in the
1088 constructor and installed using the installhull command. Once
1089 the hull is installed, its instance command is renamed and
1090 replaced as with normal snit::widgets. The original command is
1091 again accessible in the instance variable hull.
1092
1093 Note that in general it is not possible to change the widget
1094 class of a snit::widgetadaptor's hull widget.
1095
1096 See The Tk Option Database for information on how snit::wid‐
1097 getadaptors interact with the option database.
1098
1099 snit::typemethod type name arglist body
1100 Defines a new type method (or redefines an existing type method)
1101 for a previously existing type.
1102
1103 snit::method type name arglist body
1104 Defines a new instance method (or redefines an existing instance
1105 method) for a previously existing type. Note that delegated
1106 instance methods can't be redefined.
1107
1108 snit::macro name arglist body
1109 Defines a Snit macro with the specified name, arglist, and body.
1110 Macros are used to define new type and widget definition state‐
1111 ments in terms of the statements defined in this man page.
1112
1113 A macro is simply a Tcl proc that is defined in the slave inter‐
1114 preter used to compile type and widget definitions. Thus,
1115 macros have access to all of the type and widget definition
1116 statements. See Macros and Meta-programming for more details.
1117
1118 The macro name cannot be the same as any standard Tcl command,
1119 or any Snit type or widget definition statement, e.g., you can't
1120 redefine the method or delegate statements, or the standard set,
1121 list, or string commands.
1122
1123 snit::compile which type body
1124 Snit defines a type, widget, or widgetadaptor by "compiling" the
1125 definition into a Tcl script; this script is then evaluated in
1126 the Tcl interpreter, which actually defines the new type.
1127
1128 This command exposes the "compiler". Given a definition body
1129 for the named type, where which is type, widget, or widgetadap‐
1130 tor, snit::compile returns a list of two elements. The first
1131 element is the fully qualified type name; the second element is
1132 the definition script.
1133
1134 snit::compile is useful when additional processing must be done
1135 on the Snit-generated code--if it must be instrumented, for
1136 example, or run through the TclDevKit compiler. In addition,
1137 the returned script could be saved in a ".tcl" file and used to
1138 define the type as part of an application or library, thus sav‐
1139 ing the compilation overhead at application start-up. Note that
1140 the same version of Snit must be used at run-time as at compile-
1141 time.
1142
1143 THE TYPE COMMAND
1144 A type or widget definition creates a type command, which is used to
1145 create instances of the type. The type command has this form:
1146
1147 $type typemethod args...
1148 The typemethod can be any of the Standard Type Methods (e.g.,
1149 create), or any type method defined in the type definition. The
1150 subsequent args depend on the specific typemethod chosen.
1151
1152 The type command is most often used to create new instances of
1153 the type; hence, the create method is assumed if the first argu‐
1154 ment to the type command doesn't name a valid type method,
1155 unless the type definition includes delegate typemethod * or the
1156 -hasinstances pragma is set to false.
1157
1158 Furthermore, if the -hastypemethods pragma is false, then Snit
1159 type commands can be called with no arguments at all; in this
1160 case, the type command creates an instance with an automatically
1161 generated name. In other words, provided that the -hastypemeth‐
1162 ods pragma is false and the type has instances, the following
1163 commands are equivalent:
1164
1165 snit::type dog { ... }
1166
1167 set mydog [dog create %AUTO%]
1168 set mydog [dog %AUTO%]
1169 set mydog [dog]
1170
1171
1172 This doesn't work for Snit widgets, for obvious reasons.
1173
1174 Snit 1.x Incompatibility: In Snit 1.x, the above behavior is
1175 available whether -hastypemethods is true (the default) or
1176 false.
1177
1178 STANDARD TYPE METHODS
1179 In addition to any type methods in the type's definition, all type and
1180 widget commands will usually have at least the following subcommands:
1181
1182 $type create name ?option value ...?
1183 Creates a new instance of the type, giving it the specified name
1184 and calling the type's constructor.
1185
1186 For snit::types, if name is not a fully-qualified command name,
1187 it is assumed to be a name in the namespace in which the call to
1188 snit::type appears. The method returns the fully-qualified
1189 instance name.
1190
1191 For snit::widgets and snit::widgetadaptors, name must be a valid
1192 widget name; the method returns the widget name.
1193
1194 So long as name does not conflict with any defined type method
1195 name the create keyword may be omitted, unless the type defini‐
1196 tion includes delegate typemethod * or the -hasinstances pragma
1197 is set to false.
1198
1199 If the name includes the string %AUTO%, it will be replaced with
1200 the string $type$counter where $type is the type name and
1201 $counter is a counter that increments each time %AUTO% is used
1202 for this type.
1203
1204 By default, any arguments following the name will be a list of
1205 option names and their values; however, a type's constructor can
1206 specify a different argument list.
1207
1208 As of Snit V0.95, create will throw an error if the name is the
1209 same as any existing command--note that this was always true for
1210 snit::widgets and snit::widgetadaptors. You can restore the
1211 previous behavior using the -canreplace pragma.
1212
1213 $type info typevars ?pattern?
1214 Returns a list of the type's type variables (excluding Snit
1215 internal variables); all variable names are fully-qualified.
1216
1217 If pattern is given, it's used as a string match pattern; only
1218 names that match the pattern are returned.
1219
1220 $type info typemethods ?pattern?
1221 Returns a list of the names of the type's type methods. If the
1222 type has hierarchical type methods, whether locally-defined or
1223 delegated, only the first word of each will be included in the
1224 list.
1225
1226 If the type definition includes delegate typemethod *, the list
1227 will include only the names of those implicitly delegated type
1228 methods that have been called at least once and are still in the
1229 type method cache.
1230
1231 If pattern is given, it's used as a string match pattern; only
1232 names that match the pattern are returned.
1233
1234 $type info args method
1235 Returns a list containing the names of the arguments to the
1236 type's method, in order. This method cannot be applied to dele‐
1237 gated type methods.
1238
1239 $type info body method
1240 Returns the body of typemethod method. This method cannot be
1241 applied to delegated type methods.
1242
1243 $type info default method aname varname
1244 Returns a boolean value indicating whether the argument aname of
1245 the type's method has a default value (true) or not (false). If
1246 the argument has a default its value is placed into the variable
1247 varname.
1248
1249 $type info instances ?pattern?
1250 Returns a list of the type's instances. For snit::types, it
1251 will be a list of fully-qualified instance names; for snit::wid‐
1252 gets, it will be a list of Tk widget names.
1253
1254 If pattern is given, it's used as a string match pattern; only
1255 names that match the pattern are returned.
1256
1257 Snit 1.x Incompatibility: In Snit 1.x, the full multi-word
1258 names of hierarchical type methods are included in the return
1259 value.
1260
1261 $type destroy
1262 Destroys the type's instances, the type's namespace, and the
1263 type command itself.
1264
1265 THE INSTANCE COMMAND
1266 A Snit type or widget's create type method creates objects of the type;
1267 each object has a unique name that is also a Tcl command. This command
1268 is used to access the object's methods and data, and has this form:
1269
1270 $object method args...
1271 The method can be any of the Standard Instance Methods, or any
1272 instance method defined in the type definition. The subsequent
1273 args depend on the specific method chosen.
1274
1275 STANDARD INSTANCE METHODS
1276 In addition to any delegated or locally-defined instance methods in the
1277 type's definition, all Snit objects will have at least the following
1278 subcommands:
1279
1280 $object configure ?option? ?value? ...
1281 Assigns new values to one or more options. If called with one
1282 argument, an option name, returns a list describing the option,
1283 as Tk widgets do; if called with no arguments, returns a list of
1284 lists describing all options, as Tk widgets do.
1285
1286 Warning: This information will be available for delegated
1287 options only if the component to which they are delegated has a
1288 configure method that returns this same kind of information.
1289
1290 Note: Snit defines this method only if the type has at least one
1291 option.
1292
1293 $object configurelist optionlist
1294 Like configure, but takes one argument, a list of options and
1295 their values. It's mostly useful in the type constructor, but
1296 can be used anywhere.
1297
1298 Note: Snit defines this method only if the type has at least one
1299 option.
1300
1301 $object cget option
1302 Returns the option's value.
1303
1304 Note: Snit defines this method only if the type has at least one
1305 option.
1306
1307 $object destroy
1308 Destroys the object, calling the destructor and freeing all
1309 related memory.
1310
1311 Note: The destroy method isn't defined for snit::widget or
1312 snit::widgetadaptor objects; instances of these are destroyed by
1313 calling Tk's destroy command, just as normal widgets are.
1314
1315 $object info type
1316 Returns the instance's type.
1317
1318 $object info vars ?pattern?
1319 Returns a list of the object's instance variables (excluding
1320 Snit internal variables). The names are fully qualified.
1321
1322 If pattern is given, it's used as a string match pattern; only
1323 names that match the pattern are returned.
1324
1325 $object info typevars ?pattern?
1326 Returns a list of the object's type's type variables (excluding
1327 Snit internal variables). The names are fully qualified.
1328
1329 If pattern is given, it's used as a string match pattern; only
1330 names that match the pattern are returned.
1331
1332 $object info typemethods ?pattern?
1333 Returns a list of the names of the type's type methods. If the
1334 type has hierarchical type methods, whether locally-defined or
1335 delegated, only the first word of each will be included in the
1336 list.
1337
1338 If the type definition includes delegate typemethod *, the list
1339 will include only the names of those implicitly delegated type
1340 methods that have been called at least once and are still in the
1341 type method cache.
1342
1343 If pattern is given, it's used as a string match pattern; only
1344 names that match the pattern are returned.
1345
1346 Snit 1.x Incompatibility: In Snit 1.x, the full multi-word
1347 names of hierarchical type methods are included in the return
1348 value.
1349
1350 $object info options ?pattern?
1351 Returns a list of the object's option names. This always
1352 includes local options and explicitly delegated options. If
1353 unknown options are delegated as well, and if the component to
1354 which they are delegated responds to $object configure like Tk
1355 widgets do, then the result will include all possible unknown
1356 options that can be delegated to the component.
1357
1358 If pattern is given, it's used as a string match pattern; only
1359 names that match the pattern are returned.
1360
1361 Note that the return value might be different for different
1362 instances of the same type, if component object types can vary
1363 from one instance to another.
1364
1365 $object info methods ?pattern?
1366 Returns a list of the names of the instance's methods. If the
1367 type has hierarchical methods, whether locally-defined or dele‐
1368 gated, only the first word of each will be included in the list.
1369
1370 If the type definition includes delegate method *, the list will
1371 include only the names of those implicitly delegated methods
1372 that have been called at least once and are still in the method
1373 cache.
1374
1375 If pattern is given, it's used as a string match pattern; only
1376 names that match the pattern are returned.
1377
1378 Snit 1.x Incompatibility: In Snit 1.x, the full multi-word
1379 names of hierarchical type methods are included in the return
1380 value.
1381
1382 $object info args method
1383 Returns a list containing the names of the arguments to the
1384 instance's method, in order. This method cannot be applied to
1385 delegated methods.
1386
1387 $object info body method
1388 Returns the body of the instance's method method. This method
1389 cannot be applied to delegated methods.
1390
1391 $object info default method aname varname
1392 Returns a boolean value indicating whether the argument aname of
1393 the instance's method has a default value (true) or not (false).
1394 If the argument has a default its value is placed into the vari‐
1395 able varname.
1396
1397 COMMANDS FOR USE IN OBJECT CODE
1398 Snit defines the following commands for use in your object code: that
1399 is, for use in type methods, instance methods, constructors, destruc‐
1400 tors, onconfigure handlers, oncget handlers, and procs. They do not
1401 reside in the ::snit:: namespace; instead, they are created with the
1402 type, and can be used without qualification.
1403
1404 mymethod name ?args...?
1405 The mymethod command is used for formatting callback commands to
1406 be passed to other objects. It returns a command that when
1407 called will invoke method name with the specified arguments,
1408 plus of course any arguments added by the caller. In other
1409 words, both of the following commands will cause the object's
1410 dosomething method to be called when the $button is pressed:
1411
1412 $button configure -command [list $self dosomething myargument]
1413
1414 $button configure -command [mymethod dosomething myargument]
1415
1416
1417 The chief distinction between the two is that the latter form
1418 will not break if the object's command is renamed.
1419
1420 mytypemethod name ?args...?
1421 The mytypemethod command is used for formatting callback com‐
1422 mands to be passed to other objects. It returns a command that
1423 when called will invoke type method name with the specified
1424 arguments, plus of course any arguments added by the caller. In
1425 other words, both of the following commands will cause the
1426 object's dosomething type method to be called when $button is
1427 pressed:
1428
1429 $button configure -command [list $type dosomething myargument]
1430
1431 $button configure -command [mytypemethod dosomething myargument]
1432
1433
1434 Type commands cannot be renamed, so in practice there's little
1435 difference between the two forms. mytypemethod is provided for
1436 parallelism with mymethod.
1437
1438 myproc name ?args...?
1439 The myproc command is used for formatting callback commands to
1440 be passed to other objects. It returns a command that when
1441 called will invoke the type proc name with the specified argu‐
1442 ments, plus of course any arguments added by the caller. In
1443 other words, both of the following commands will cause the
1444 object's dosomething proc to be called when $button is pressed:
1445
1446 $button configure -command [list ${type}::dosomething myargument]
1447
1448 $button configure -command [myproc dosomething myargument]
1449
1450
1451 myvar name
1452 Given an instance variable name, returns the fully qualified
1453 name. Use this if you're passing the variable to some other
1454 object, e.g., as a -textvariable to a Tk label widget.
1455
1456 mytypevar name
1457 Given an type variable name, returns the fully qualified name.
1458 Use this if you're passing the variable to some other object,
1459 e.g., as a -textvariable to a Tk label widget.
1460
1461 from argvName option ?defvalue?
1462 The from command plucks an option value from a list of options
1463 and their values, such as is passed into a type's constructor.
1464 argvName must be the name of a variable containing such a list;
1465 option is the name of the specific option.
1466
1467 from looks for option in the option list. If it is found, it
1468 and its value are removed from the list, and the value is
1469 returned. If option doesn't appear in the list, then the def‐
1470 value is returned. If the option is locally-defined option, and
1471 defvalue is not specified, then the option's default value as
1472 specified in the type definition will be returned instead.
1473
1474 install compName using objType objName args...
1475 Creates a new object of type objType called objName and installs
1476 it as component compName, as described in Components and Delega‐
1477 tion. Any additional args... are passed along with the name to
1478 the objType command. If this is a snit::type, then the follow‐
1479 ing two commands are equivalent:
1480
1481 install myComp using myObjType $self.myComp args...
1482
1483 set myComp [myObjType $self.myComp args...]
1484
1485
1486 Note that whichever method is used, compName must still be
1487 declared in the type definition using component, or must be ref‐
1488 erenced in at least one delegate statement.
1489
1490 If this is a snit::widget or snit::widgetadaptor, and if options
1491 have been delegated to component compName, then those options
1492 will receive default values from the Tk option database. Note
1493 that it doesn't matter whether the component to be installed is
1494 a widget or not. See The Tk Option Database for more informa‐
1495 tion.
1496
1497 install cannot be used to install type components; just assign
1498 the type component's command name to the type component's vari‐
1499 able instead.
1500
1501 installhull using widgetType args...
1502
1503 installhull name
1504 The constructor of a snit::widgetadaptor must create a widget to
1505 be the object's hull component; the widget is installed as the
1506 hull component using this command. Note that the installed wid‐
1507 get's name must be $win. This command has two forms.
1508
1509 The first form specifies the widgetType and the args... (that
1510 is, the hardcoded option list) to use in creating the hull.
1511 Given this form, installhull creates the hull widget, and ini‐
1512 tializes any options delegated to the hull from the Tk option
1513 database.
1514
1515 In the second form, the hull widget has already been created;
1516 note that its name must be "$win". In this case, the Tk option
1517 database is not queried for any options delegated to the hull.
1518 The longer form is preferred; however, the shorter form allows
1519 the programmer to adapt a widget created elsewhere, which is
1520 sometimes useful. For example, it can be used to adapt a "page"
1521 widget created by a BWidgets tabbed notebook or pages manager
1522 widget.
1523
1524 See The Tk Option Database for more information about snit::wid‐
1525 getadaptors and the option database.
1526
1527 variable name
1528 Normally, instance variables are defined in the type definition
1529 along with the options, methods, and so forth; such instance
1530 variables are automatically visible in all instance code (e.g.,
1531 method bodies). However, instance code can use the variable
1532 command to declare instance variables that don't appear in the
1533 type definition, and also to bring variables from other names‐
1534 paces into scope in the usual way.
1535
1536 It's generally clearest to define all instance variables in the
1537 type definition, and omit declaring them in methods and so
1538 forth.
1539
1540 Note that this is an instance-specific version of the standard
1541 Tcl ::variable command.
1542
1543 typevariable name
1544 Normally, type variables are defined in the type definition,
1545 along with the instance variables; such type variables are auto‐
1546 matically visible in all of the type's code. However, type
1547 methods, instance methods and so forth can use typevariable to
1548 declare type variables that don't appear in the type definition.
1549
1550 It's generally clearest to declare all type variables in the
1551 type definition, and omit declaring them in methods, type meth‐
1552 ods, etc.
1553
1554 varname name
1555 Deprecated. Use myvar instead.
1556
1557 Given an instance variable name, returns the fully qualified
1558 name. Use this if you're passing the variable to some other
1559 object, e.g., as a -textvariable to a Tk label widget.
1560
1561 typevarname name
1562 Deprecated. Use mytypevar instead.
1563
1564 Given a type variable name, returns the fully qualified name.
1565 Use this if you're passing the type variable to some other
1566 object, e.g., as a -textvariable to a Tk label widget.
1567
1568 codename name
1569 Deprecated. Use myproc instead. Given the name of a proc (but
1570 not a type or instance method), returns the fully-qualified com‐
1571 mand name, suitable for passing as a callback.
1572
1573 COMPONENTS AND DELEGATION
1574 When an object includes other objects, as when a toolbar contains but‐
1575 tons or a GUI object contains an object that references a database, the
1576 included object is called a component. The standard way to handle com‐
1577 ponent objects owned by a Snit object is to declare them using compo‐
1578 nent, which creates a component instance variable. In the following
1579 example, a dog object has a tail object:
1580
1581 snit::type dog {
1582 component mytail
1583
1584 constructor {args} {
1585 set mytail [tail %AUTO% -partof $self]
1586 $self configurelist $args
1587 }
1588
1589 method wag {} {
1590 $mytail wag
1591 }
1592 }
1593
1594 snit::type tail {
1595 option -length 5
1596 option -partof
1597 method wag {} { return "Wag, wag, wag."}
1598 }
1599
1600
1601 Because the tail object's name is stored in an instance variable, it's
1602 easily accessible in any method.
1603
1604 The install command provides an alternate way to create and install the
1605 component:
1606
1607 snit::type dog {
1608 component mytail
1609
1610 constructor {args} {
1611 install mytail using tail %AUTO% -partof $self
1612 $self configurelist $args
1613 }
1614
1615 method wag {} {
1616 $mytail wag
1617 }
1618 }
1619
1620
1621 For snit::types, the two methods are equivalent; for snit::widgets and
1622 snit::widgetadaptors, the install command properly initializes the wid‐
1623 get's options by querying The Tk Option Database.
1624
1625 In the above examples, the dog object's wag method simply calls the
1626 tail component's wag method. In OO jargon, this is called delegation.
1627 Snit provides an easier way to do this:
1628
1629 snit::type dog {
1630 delegate method wag to mytail
1631
1632 constructor {args} {
1633 install mytail using tail %AUTO% -partof $self
1634 $self configurelist $args
1635 }
1636 }
1637
1638
1639 The delegate statement in the type definition implicitly defines the
1640 instance variable mytail to hold the component's name (though it's good
1641 form to use component to declare it explicitly); it also defines the
1642 dog object's wag method, delegating it to the mytail component.
1643
1644 If desired, all otherwise unknown methods can be delegated to a spe‐
1645 cific component:
1646
1647 snit::type dog {
1648 delegate method * to mytail
1649
1650 constructor {args} {
1651 set mytail [tail %AUTO% -partof $self]
1652 $self configurelist $args
1653 }
1654
1655 method bark { return "Bark, bark, bark!" }
1656 }
1657
1658
1659 In this case, a dog object will handle its own bark method; but wag
1660 will be passed along to mytail. Any other method, being recognized by
1661 neither dog nor tail, will simply raise an error.
1662
1663 Option delegation is similar to method delegation, except for the
1664 interactions with the Tk option database; this is described in The Tk
1665 Option Database.
1666
1667 TYPE COMPONENTS AND DELEGATION
1668 The relationship between type components and instance components is
1669 identical to that between type variables and instance variables, and
1670 that between type methods and instance methods. Just as an instance
1671 component is an instance variable that holds the name of a command, so
1672 a type component is a type variable that holds the name of a command.
1673 In essence, a type component is a component that's shared by every
1674 instance of the type.
1675
1676 Just as delegate method can be used to delegate methods to instance
1677 components, as described in Components and Delegation, so delegate
1678 typemethod can be used to delegate type methods to type components.
1679
1680 Note also that as of Snit 0.95 delegate method can delegate methods to
1681 both instance components and type components.
1682
1683 THE TK OPTION DATABASE
1684 This section describes how Snit interacts with the Tk option database,
1685 and assumes the reader has a working knowledge of the option database
1686 and its uses. The book Practical Programming in Tcl and Tk by Welch et
1687 al has a good introduction to the option database, as does Effective
1688 Tcl/Tk Programming.
1689
1690 Snit is implemented so that most of the time it will simply do the
1691 right thing with respect to the option database, provided that the wid‐
1692 get developer does the right thing by Snit. The body of this section
1693 goes into great deal about what Snit requires. The following is a
1694 brief statement of the requirements, for reference.
1695
1696 · If the snit::widget's default widget class is not what is
1697 desired, set it explicitly using widgetclass in the widget defi‐
1698 nition.
1699
1700 · When defining or delegating options, specify the resource and
1701 class names explicitly when if the defaults aren't what you
1702 want.
1703
1704 · Use installhull using to install the hull for snit::widgetadap‐
1705 tors.
1706
1707 · Use install to install all other components.
1708
1709 The interaction of Tk widgets with the option database is a complex
1710 thing; the interaction of Snit with the option database is even more
1711 so, and repays attention to detail.
1712
1713 Setting the widget class: Every Tk widget has a widget class. For Tk
1714 widgets, the widget class name is the just the widget type name with an
1715 initial capital letter, e.g., the widget class for button widgets is
1716 "Button".
1717
1718 Similarly, the widget class of a snit::widget defaults to the unquali‐
1719 fied type name with the first letter capitalized. For example, the
1720 widget class of
1721
1722 snit::widget ::mylibrary::scrolledText { ... }
1723
1724 is "ScrolledText". The widget class can also be set explicitly using
1725 the widgetclass statement within the snit::widget definition.
1726
1727 Any widget can be used as the hulltype provided that it supports the
1728 -class option for changing its widget class name. See the discussion
1729 of the hulltype command, above. The user may pass -class to the widget
1730 at instantion.
1731
1732 The widget class of a snit::widgetadaptor is just the widget class of
1733 its hull widget; this cannot be changed unless the hull widget supports
1734 -class, in which case it will usually make more sense to use snit::wid‐
1735 get rather than snit::widgetadaptor.
1736
1737 Setting option resource names and classes: In Tk, every option has
1738 three names: the option name, the resource name, and the class name.
1739 The option name begins with a hyphen and is all lowercase; it's used
1740 when creating widgets, and with the configure and cget commands.
1741
1742 The resource and class names are used to initialize option default val‐
1743 ues by querying the Tk option database. The resource name is usually
1744 just the option name minus the hyphen, but may contain uppercase let‐
1745 ters at word boundaries; the class name is usually just the resource
1746 name with an initial capital, but not always. For example, here are
1747 the option, resource, and class names for several text widget options:
1748
1749 -background background Background
1750 -borderwidth borderWidth BorderWidth
1751 -insertborderwidth insertBorderWidth BorderWidth
1752 -padx padX Pad
1753
1754
1755 As is easily seen, sometimes the resource and class names can be
1756 inferred from the option name, but not always.
1757
1758 Snit options also have a resource name and a class name. By default,
1759 these names follow the rule given above: the resource name is the
1760 option name without the hyphen, and the class name is the resource name
1761 with an initial capital. This is true for both locally-defined options
1762 and explicitly delegated options:
1763
1764 snit::widget mywidget {
1765 option -background
1766 delegate option -borderwidth to hull
1767 delegate option * to text
1768 # ...
1769 }
1770
1771
1772 In this case, the widget class name is "Mywidget". The widget has the
1773 following options: -background, which is locally defined, and -border‐
1774 width, which is explicitly delegated; all other widgets are delegated
1775 to a component called "text", which is probably a Tk text widget. If
1776 so, mywidget has all the same options as a text widget. The option,
1777 resource, and class names are as follows:
1778
1779 -background background Background
1780 -borderwidth borderwidth Borderwidth
1781 -padx padX Pad
1782
1783
1784 Note that the locally defined option, -background, happens to have the
1785 same three names as the standard Tk -background option; and -pad, which
1786 is delegated implicitly to the text component, has the same three names
1787 for mywidget as it does for the text widget. -borderwidth, on the
1788 other hand, has different resource and class names than usual, because
1789 the internal word "width" isn't capitalized. For consistency, it
1790 should be; this is done as follows:
1791
1792 snit::widget mywidget {
1793 option -background
1794 delegate option {-borderwidth borderWidth} to hull
1795 delegate option * to text
1796 # ...
1797 }
1798
1799
1800 The class name will default to "BorderWidth", as expected.
1801
1802 Suppose, however, that mywidget also delegated -padx and -pady to the
1803 hull. In this case, both the resource name and the class name must be
1804 specified explicitly:
1805
1806 snit::widget mywidget {
1807 option -background
1808 delegate option {-borderwidth borderWidth} to hull
1809 delegate option {-padx padX Pad} to hull
1810 delegate option {-pady padY Pad} to hull
1811 delegate option * to text
1812 # ...
1813 }
1814
1815
1816 Querying the option database: If you set your widgetclass and option
1817 names as described above, Snit will query the option database when each
1818 instance is created, and will generally do the right thing when it
1819 comes to querying the option database. The remainder of this section
1820 goes into the gory details.
1821
1822 Initializing locally defined options: When an instance of a snit::wid‐
1823 get is created, its locally defined options are initialized as follows:
1824 each option's resource and class names are used to query the Tk option
1825 database. If the result is non-empty, it is used as the option's
1826 default; otherwise, the default hardcoded in the type definition is
1827 used. In either case, the default can be overridden by the caller.
1828 For example,
1829
1830 option add *Mywidget.texture pebbled
1831
1832 snit::widget mywidget {
1833 option -texture smooth
1834 # ...
1835 }
1836
1837 mywidget .mywidget -texture greasy
1838
1839
1840 Here, -texture would normally default to "smooth", but because of the
1841 entry added to the option database it defaults to "pebbled". However,
1842 the caller has explicitly overridden the default, and so the new widget
1843 will be "greasy".
1844
1845 Initializing options delegated to the hull: A snit::widget's hull is a
1846 widget, and given that its class has been set it is expected to query
1847 the option database for itself. The only exception concerns options
1848 that are delegated to it with a different name. Consider the following
1849 code:
1850
1851 option add *Mywidget.borderWidth 5
1852 option add *Mywidget.relief sunken
1853 option add *Mywidget.hullbackground red
1854 option add *Mywidget.background green
1855
1856 snit::widget mywidget {
1857 delegate option -borderwidth to hull
1858 delegate option -hullbackground to hull as -background
1859 delegate option * to hull
1860 # ...
1861 }
1862
1863 mywidget .mywidget
1864
1865 set A [.mywidget cget -relief]
1866 set B [.mywidget cget -hullbackground]
1867 set C [.mywidget cget -background]
1868 set D [.mywidget cget -borderwidth]
1869
1870
1871 The question is, what are the values of variables A, B, C and D?
1872
1873 The value of A is "sunken". The hull is a Tk frame that has been given
1874 the widget class "Mywidget"; it will automatically query the option
1875 database and pick up this value. Since the -relief option is implic‐
1876 itly delegated to the hull, Snit takes no action.
1877
1878 The value of B is "red". The hull will automatically pick up the value
1879 "green" for its -background option, just as it picked up the -relief
1880 value. However, Snit knows that -hullbackground is mapped to the
1881 hull's -background option; hence, it queries the option database for
1882 -hullbackground and gets "red" and updates the hull accordingly.
1883
1884 The value of C is also "red", because -background is implicitly dele‐
1885 gated to the hull; thus, retrieving it is the same as retrieving -hull‐
1886 background. Note that this case is unusual; in practice, -background
1887 would probably be explicitly delegated to some other component.
1888
1889 The value of D is "5", but not for the reason you think. Note that as
1890 it is defined above, the resource name for -borderwidth defaults to
1891 "borderwidth", whereas the option database entry is "borderWidth". As
1892 with -relief, the hull picks up its own -borderwidth option before Snit
1893 does anything. Because the option is delegated under its own name,
1894 Snit assumes that the correct thing has happened, and doesn't worry
1895 about it any further.
1896
1897 For snit::widgetadaptors, the case is somewhat altered. Widget adap‐
1898 tors retain the widget class of their hull, and the hull is not created
1899 automatically by Snit. Instead, the snit::widgetadaptor must call
1900 installhull in its constructor. The normal way to do this is as fol‐
1901 lows:
1902
1903 snit::widgetadaptor mywidget {
1904 # ...
1905 constructor {args} {
1906 # ...
1907 installhull using text -foreground white
1908 #
1909 }
1910 #...
1911 }
1912
1913
1914 In this case, the installhull command will create the hull using a com‐
1915 mand like this:
1916
1917 set hull [text $win -foreground white]
1918
1919
1920 The hull is a text widget, so its widget class is "Text". Just as with
1921 snit::widget hulls, Snit assumes that it will pick up all of its normal
1922 option values automatically; options delegated from a different name
1923 are initialized from the option database in the same way.
1924
1925 Initializing options delegated to other components: Non-hull components
1926 are matched against the option database in two ways. First, a compo‐
1927 nent widget remains a widget still, and therefore is initialized from
1928 the option database in the usual way. Second, the option database is
1929 queried for all options delegated to the component, and the component
1930 is initialized accordingly--provided that the install command is used
1931 to create it.
1932
1933 Before option database support was added to Snit, the usual way to cre‐
1934 ate a component was to simply create it in the constructor and assign
1935 its command name to the component variable:
1936
1937 snit::widget mywidget {
1938 delegate option -background to myComp
1939
1940 constructor {args} {
1941 set myComp [text $win.text -foreground black]
1942 }
1943 }
1944
1945
1946 The drawback of this method is that Snit has no opportunity to initial‐
1947 ize the component properly. Hence, the following approach is now used:
1948
1949 snit::widget mywidget {
1950 delegate option -background to myComp
1951
1952 constructor {args} {
1953 install myComp using text $win.text -foreground black
1954 }
1955 }
1956
1957
1958 The install command does the following:
1959
1960 · Builds a list of the options explicitly included in the install
1961 command -- in this case, -foreground.
1962
1963 · Queries the option database for all options delegated explicitly
1964 to the named component.
1965
1966 · Creates the component using the specified command, after insert‐
1967 ing into it a list of options and values read from the option
1968 database. Thus, the explicitly included options (-foreground)
1969 will override anything read from the option database.
1970
1971 · If the widget definition implicitly delegated options to the
1972 component using delegate option *, then Snit calls the newly
1973 created component's configure method to receive a list of all of
1974 the component's options. From this Snit builds a list of
1975 options implicitly delegated to the component that were not
1976 explicitly included in the install command. For all such
1977 options, Snit queries the option database and configures the
1978 component accordingly.
1979
1980 Non-widget components: The option database is never queried for
1981 snit::types, since it can only be queried given a Tk widget name. How‐
1982 ever, snit::widgets can have non-widget components. And if options are
1983 delegated to those components, and if the install command is used to
1984 install those components, then they will be initialized from the option
1985 database just as widget components are.
1986
1987 MACROS AND META-PROGRAMMING
1988 The snit::macro command enables a certain amount of meta-programming
1989 with Snit classes. For example, suppose you like to define properties:
1990 instance variables that have set/get methods. Your code might look
1991 like this:
1992
1993 snit::type dog {
1994 variable mood happy
1995
1996 method getmood {} {
1997 return $mood
1998 }
1999
2000 method setmood {newmood} {
2001 set mood $newmood
2002 }
2003 }
2004
2005 That's nine lines of text per property. Or, you could define the fol‐
2006 lowing snit::macro:
2007
2008 snit::macro property {name initValue} {
2009 variable $name $initValue
2010
2011 method get$name {} "return $name"
2012
2013 method set$name {value} "set $name \$value"
2014 }
2015
2016 Note that a snit::macro is just a normal Tcl proc defined in the slave
2017 interpreter used to compile type and widget definitions; as a result,
2018 it has access to all the commands used to define types and widgets.
2019
2020 Given this new macro, you can define a property in one line of code:
2021
2022 snit::type dog {
2023 property mood happy
2024 }
2025
2026 Within a macro, the commands variable and proc refer to the Snit type-
2027 definition commands, not the standard Tcl commands. To get the stan‐
2028 dard Tcl commands, use _variable and _proc.
2029
2030 Because a single slave interpreter is used for compiling all Snit types
2031 and widgets in the application, there's the possibility of macro name
2032 collisions. If you're writing a reuseable package using Snit, and you
2033 use some snit::macros, define them in your package namespace:
2034
2035 snit::macro mypkg::property {name initValue} { ... }
2036
2037 snit::type dog {
2038 mypkg::property mood happy
2039 }
2040
2041 This leaves the global namespace open for application authors.
2042
2043 VALIDATION TYPES
2044 A validation type is an object that can be used to validate Tcl values
2045 of a particular kind. For example, snit::integer is used to validate
2046 that a Tcl value is an integer.
2047
2048 Every validation type has a validate method which is used to do the
2049 validation. This method must take a single argument, the value to be
2050 validated; further, it must do nothing if the value is valid, but throw
2051 an error if the value is invalid:
2052
2053 snit::integer validate 5 ;# Does nothing
2054 snit::integer validate 5.0 ;# Throws an error (not an integer!)
2055
2056
2057 The validate method will always return the validated value on success,
2058 and throw the -errorcode INVALID on error.
2059
2060 Snit defines a family of validation types, all of which are implemented
2061 as snit::type's. They can be used as is; in addition, their instances
2062 serve as parameterized subtypes. For example, a probability is a num‐
2063 ber between 0.0 and 1.0 inclusive:
2064
2065 snit::double probability -min 0.0 -max 1.0
2066
2067 The example above creates an instance of snit::double--a validation
2068 subtype--called probability, which can be used to validate probability
2069 values:
2070
2071 probability validate 0.5 ;# Does nothing
2072 probability validate 7.9 ;# Throws an error
2073
2074 Validation subtypes can be defined explicitly, as in the above example;
2075 when a locally-defined option's -type is specified, they may also be
2076 created on the fly:
2077
2078 snit::enum ::dog::breed -values {mutt retriever sheepdog}
2079
2080 snit::type dog {
2081 # Define subtypes on the fly...
2082 option -breed -type {
2083 snit::enum -values {mutt retriever sheepdog}
2084 }
2085
2086 # Or use predefined subtypes...
2087 option -breed -type ::dog::breed
2088 }
2089
2090
2091 Any object that has a validate method with the semantics described
2092 above can be used as a validation type; see Defining Validation Types
2093 for information on how to define new ones.
2094
2095 Snit defines the following validation types:
2096
2097 snit::boolean validate ?value?
2098
2099 snit::boolean name
2100 Validates Tcl boolean values: 1, 0, on, off, yes, no, true,
2101 false. It's possible to define subtypes--that is, instances--of
2102 snit::boolean, but as it has no options there's no reason to do
2103 so.
2104
2105 snit::double validate ?value?
2106
2107 snit::double name ?option value...?
2108 Validates floating-point values. Subtypes may be created with
2109 the following options:
2110
2111 -min min
2112 Specifies a floating-point minimum bound; a value is
2113 invalid if it is strictly less than min.
2114
2115 -max max
2116 Specifies a floating-point maximum bound; a value is
2117 invalid if it is strictly greater than max.
2118
2119 snit::enum validate ?value?
2120
2121 snit::enum name ?option value...?
2122 Validates that a value comes from an enumerated list. The base
2123 type is of little use by itself, as only subtypes actually have
2124 an enumerated list to validate against. Subtypes may be created
2125 with the following options:
2126
2127 -values list
2128 Specifies a list of valid values. A value is valid if
2129 and only if it's included in the list.
2130
2131 snit::fpixels validate ?value?
2132
2133 snit::fpixels name ?option value...?
2134 Tk programs only. Validates screen distances, in any of the
2135 forms accepted by winfo fpixels. Subtypes may be created with
2136 the following options:
2137
2138 -min min
2139 Specifies a minimum bound; a value is invalid if it is
2140 strictly less than min. The bound may be expressed in
2141 any of the forms accepted by winfo fpixels.
2142
2143 -max max
2144 Specifies a maximum bound; a value is invalid if it is
2145 strictly greater than max. The bound may be expressed in
2146 any of the forms accepted by winfo fpixels.
2147
2148 snit::integer validate ?value?
2149
2150 snit::integer name ?option value...?
2151 Validates integer values. Subtypes may be created with the fol‐
2152 lowing options:
2153
2154 -min min
2155 Specifies an integer minimum bound; a value is invalid if
2156 it is strictly less than min.
2157
2158 -max max
2159 Specifies an integer maximum bound; a value is invalid if
2160 it is strictly greater than max.
2161
2162 snit::listtype validate ?value?
2163
2164 snit::listtype name ?option value...?
2165 Validates Tcl lists. Subtypes may be created with the following
2166 options:
2167
2168 -minlen min
2169 Specifies a minimum list length; the value is invalid if
2170 it has fewer than min elements. Defaults to 0.
2171
2172 -maxlen max
2173 Specifies a maximum list length; the value is invalid if
2174 it more than max elements.
2175
2176 -type type
2177 Specifies the type of the list elements; type must be the
2178 name of a validation type or subtype. In the following
2179 example, the value of -numbers must be a list of inte‐
2180 gers.
2181
2182 option -numbers -type {snit::listtype -type snit::integer}
2183
2184
2185 Note that this option doesn't support defining new vali‐
2186 dation subtypes on the fly; that is, the following code
2187 will not work (yet, anyway):
2188
2189 option -numbers -type {
2190 snit::listtype -type {snit::integer -min 5}
2191 }
2192
2193
2194 Instead, define the subtype explicitly:
2195
2196 snit::integer gt4 -min 5
2197
2198 snit::type mytype {
2199 option -numbers -type {snit::listtype -type gt4}
2200 }
2201
2202
2203 snit::pixels validate ?value?
2204
2205 snit::pixels name ?option value...?
2206 Tk programs only. Validates screen distances, in any of the
2207 forms accepted by winfo pixels. Subtypes may be created with the
2208 following options:
2209
2210 -min min
2211 Specifies a minimum bound; a value is invalid if it is
2212 strictly less than min. The bound may be expressed in
2213 any of the forms accepted by winfo pixels.
2214
2215 -max max
2216 Specifies a maximum bound; a value is invalid if it is
2217 strictly greater than max. The bound may be expressed in
2218 any of the forms accepted by winfo pixels.
2219
2220 snit::stringtype validate ?value?
2221
2222 snit::stringtype name ?option value...?
2223 Validates Tcl strings. The base type is of little use by itself,
2224 since very Tcl value is also a valid string. Subtypes may be
2225 created with the following options:
2226
2227 -minlen min
2228 Specifies a minimum string length; the value is invalid
2229 if it has fewer than min characters. Defaults to 0.
2230
2231 -maxlen max
2232 Specifies a maximum string length; the value is invalid
2233 if it has more than max characters.
2234
2235 -glob pattern
2236 Specifies a string match pattern; the value is invalid if
2237 it doesn't match the pattern.
2238
2239 -regexp regexp
2240 Specifies a regular expression; the value is invalid if
2241 it doesn't match the regular expression.
2242
2243 -nocase flag
2244 By default, both -glob and -regexp matches are case-sen‐
2245 sitive. If -nocase is set to true, then both -glob and
2246 -regexp matches are case-insensitive.
2247
2248 snit::window validate ?value?
2249
2250 snit::window name
2251 Tk programs only. Validates Tk window names. The value must
2252 cause winfo exists to return true; otherwise, the value is
2253 invalid. It's possible to define subtypes--that is,
2254 instances--of snit::window, but as it has no options at present
2255 there's no reason to do so.
2256
2257 DEFINING VALIDATION TYPES
2258 There are three ways to define a new validation type: as a subtype of
2259 one of Snit's validation types, as a validation type command, and as a
2260 full-fledged validation type similar to those provided by Snit. Defin‐
2261 ing subtypes of Snit's validation types is described above, under Vali‐
2262 dation Types.
2263
2264 The next simplest way to create a new validation type is as a valida‐
2265 tion type command. A validation type is simply an object that has a
2266 validate method; the validate method must take one argument, a value,
2267 return the value if it is valid, and throw an error with -errorcode
2268 INVALID if the value is invalid. This can be done with a simple proc.
2269 For example, the snit::boolean validate type could have been imple‐
2270 mented like this:
2271
2272 proc ::snit::boolean {"validate" value} {
2273 if {![string is boolean -strict $value]} {
2274 return -code error -errorcode INVALID "invalid boolean \"$value\", should be one of: 1, 0, ..."
2275 }
2276
2277 return $value
2278 }
2279
2280 A validation type defined in this way cannot be subtyped, of course;
2281 but for many applications this will be sufficient.
2282
2283 Finally, one can define a full-fledged, subtype-able validation type as
2284 a snit::type. Here's a skeleton to get you started:
2285
2286 snit::type myinteger {
2287 # First, define any options you'd like to use to define
2288 # subtypes. Give them defaults such that they won't take
2289 # effect if they aren't used, and marked them "read-only".
2290 # After all, you shouldn't be changing their values after
2291 # a subtype is defined.
2292 #
2293 # For example:
2294
2295 option -min -default "" -readonly 1
2296 option -max -default "" -readonly 1
2297
2298 # Next, define a "validate" type method which should do the
2299 # validation in the basic case. This will allow the
2300 # type command to be used as a validation type.
2301
2302 typemethod validate {value} {
2303 if {![string is integer -strict $value]} {
2304 return -code error -errorcode INVALID "invalid value \"$value\", expected integer"
2305 }
2306
2307 return $value
2308 }
2309
2310 # Next, the constructor should validate the subtype options,
2311 # if any. Since they are all readonly, we don't need to worry
2312 # about validating the options on change.
2313
2314 constructor {args} {
2315 # FIRST, get the options
2316 $self configurelist $args
2317
2318 # NEXT, validate them.
2319
2320 # I'll leave this to your imagination.
2321 }
2322
2323 # Next, define a "validate" instance method; its job is to
2324 # validate values for subtypes.
2325
2326 method validate {value} {
2327 # First, call the type method to do the basic validation.
2328 $type validate $value
2329
2330 # Now we know it's a valid integer.
2331
2332 if {("" != $options(-min) && $value < $options(-min)) ||
2333 ("" != $options(-max) && $value > $options(-max))} {
2334 # It's out of range; format a detailed message about
2335 # the error, and throw it.
2336
2337 set msg "...."
2338
2339 return -code error -errorcode INVALID $msg
2340 }
2341
2342 # Otherwise, if it's valid just return it.
2343 return $valid
2344 }
2345 }
2346
2347 And now you have a type that can be subtyped.
2348
2349 The file "validate.tcl" in the Snit distribution defines all of Snit's
2350 validation types; you can find the complete implementation for
2351 snit::integer and the other types there, to use as examples for your
2352 own types.
2353
2355 If you have problems, find bugs, or new ideas you are hereby cordially
2356 invited to submit a report of your problem, bug, or idea as explained
2357 in the section Bugs, Ideas, Feedback below.
2358
2359 Additionally, you might wish to join the Snit mailing list; see
2360 http://www.wjduquette.com/snit for details.
2361
2362 One particular area to watch is using snit::widgetadaptor to adapt
2363 megawidgets created by other megawidget packages; correct widget
2364 destruction depends on the order of the <Destroy> bindings. The wisest
2365 course is simply not to do this.
2366
2368 · Error stack traces returned by Snit 1.x are extremely ugly and
2369 typically contain far too much information about Snit internals.
2370 The error messages are much improved in Snit 2.2.
2371
2372 · Also see the Project Trackers as explained in the section Bugs,
2373 Ideas, Feedback below.
2374
2376 During the course of developing Notebook (See http://www.wjdu‐
2377 quette.com/notebook), my Tcl-based personal notebook application, I
2378 found I was writing it as a collection of objects. I wasn't using any
2379 particular object-oriented framework; I was just writing objects in
2380 pure Tcl following the guidelines in my Guide to Object Commands (see
2381 http://www.wjduquette.com/tcl/objects.html), along with a few other
2382 tricks I'd picked up since. And though it was working well, it quickly
2383 became tiresome because of the amount of boilerplate code associated
2384 with each new object type.
2385
2386 So that was one thing--tedium is a powerful motivator. But the other
2387 thing I noticed is that I wasn't using inheritance at all, and I wasn't
2388 missing it. Instead, I was using delegation: objects that created
2389 other objects and delegated methods to them.
2390
2391 And I said to myself, "This is getting tedious...there has got to be a
2392 better way." And one afternoon, on a whim, I started working on Snit,
2393 an object system that works the way Tcl works. Snit doesn't support
2394 inheritance, but it's great at delegation, and it makes creating megaw‐
2395 idgets easy.
2396
2397 If you have any comments or suggestions (or bug reports!) don't hesi‐
2398 tate to send me e-mail at will@wjduquette.com. In addition, there's a
2399 Snit mailing list; you can find out more about it at the Snit home page
2400 (see http://www.wjduquette.com/snit).
2401
2403 Snit has been designed and implemented from the very beginning by
2404 William H. Duquette. However, much credit belongs to the following
2405 people for using Snit and providing me with valuable feedback: Rolf
2406 Ade, Colin McCormack, Jose Nazario, Jeff Godfrey, Maurice Diamanti,
2407 Egon Pasztor, David S. Cargo, Tom Krehbiel, Michael Cleverly, Andreas
2408 Kupries, Marty Backe, Andy Goth, Jeff Hobbs, Brian Griffin, Donal Fel‐
2409 lows, Miguel Sofer, Kenneth Green, and Anton Kovalenko. If I've for‐
2410 gotten anyone, my apologies; let me know and I'll add your name to the
2411 list.
2412
2414 This document, and the package it describes, will undoubtedly contain
2415 bugs and other problems. Please report such in the category snit of
2416 the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist]. Please
2417 also report any ideas for enhancements you may have for either package
2418 and/or documentation.
2419
2420 When proposing code changes, please provide unified diffs, i.e the out‐
2421 put of diff -u.
2422
2423 Note further that attachments are strongly preferred over inlined
2424 patches. Attachments can be made by going to the Edit form of the
2425 ticket immediately after its creation, and then using the left-most
2426 button in the secondary navigation bar.
2427
2429 BWidget, C++, Incr Tcl, Snit, adaptors, class, mega widget, object,
2430 object oriented, type, widget, widget adaptors
2431
2433 Programming tools
2434
2436 Copyright (c) 2003-2009, by William H. Duquette
2437
2438
2439
2440
2441tcllib 2.3.2 snit(n)