1
2[//000000001]: # (snitfaq \- Snit's Not Incr Tcl, OO system)
3[//000000002]: # (Generated from file 'snitfaq\.man' by tcllib/doctools with format 'markdown')
4[//000000003]: # (Copyright © 2003\-2006, by William H\. Duquette)
5[//000000004]: # (snitfaq\(n\) 2\.2 tcllib "Snit's Not Incr Tcl, OO system")
6
7<hr> [ <a href="../../../../toc.md">Main Table Of Contents</a> &#124; <a
8href="../../../toc.md">Table Of Contents</a> &#124; <a
9href="../../../../index.md">Keyword Index</a> &#124; <a
10href="../../../../toc0.md">Categories</a> &#124; <a
11href="../../../../toc1.md">Modules</a> &#124; <a
12href="../../../../toc2.md">Applications</a> ] <hr>
13
14# NAME
15
16snitfaq \- Snit Frequently Asked Questions
17
18# <a name='toc'></a>Table Of Contents
19
20  - [Table Of Contents](#toc)
21
22  - [Description](#section1)
23
24  - [OVERVIEW](#section2)
25
26      - [What is this document?](#subsection1)
27
28      - [What is Snit?](#subsection2)
29
30      - [What version of Tcl does Snit require?](#subsection3)
31
32      - [Where can I download Snit?](#subsection4)
33
34      - [What are Snit's goals?](#subsection5)
35
36      - [How is Snit different from other OO frameworks?](#subsection6)
37
38      - [What can I do with Snit?](#subsection7)
39
40  - [SNIT VERSIONS](#section3)
41
42      - [Which version of Snit should I use?](#subsection8)
43
44      - [How do I select the version of Snit I want to use?](#subsection9)
45
46      - [How are Snit 1\.3 and Snit 2\.2 incompatible?](#subsection10)
47
48      - [Are there other differences between Snit 1\.x and Snit
49        2\.2?](#subsection11)
50
51  - [OBJECTS](#section4)
52
53      - [What is an object?](#subsection12)
54
55      - [What is an abstract data type?](#subsection13)
56
57      - [What kinds of abstract data types does Snit
58        provide?](#subsection14)
59
60      - [What is a snit::type?](#subsection15)
61
62      - [What is a snit::widget?, the short story](#subsection16)
63
64      - [What is a snit::widgetadaptor?, the short story](#subsection17)
65
66      - [How do I create an instance of a snit::type?](#subsection18)
67
68      - [How do I refer to an object indirectly?](#subsection19)
69
70      - [How can I generate the object name automatically?](#subsection20)
71
72      - [Can types be renamed?](#subsection21)
73
74      - [Can objects be renamed?](#subsection22)
75
76      - [How do I destroy a Snit object?](#subsection23)
77
78  - [INSTANCE METHODS](#section5)
79
80      - [What is an instance method?](#subsection24)
81
82      - [How do I define an instance method?](#subsection25)
83
84      - [How does a client call an instance method?](#subsection26)
85
86      - [How does an instance method call another instance
87        method?](#subsection27)
88
89      - [Are there any limitations on instance method
90        names?](#subsection28)
91
92      - [What is a hierarchical method?](#subsection29)
93
94      - [How do I define a hierarchical method?](#subsection30)
95
96      - [How do I call hierarchical methods?](#subsection31)
97
98      - [How do I make an instance method private?](#subsection32)
99
100      - [Are there any limitations on instance method
101        arguments?](#subsection33)
102
103      - [What implicit arguments are passed to each instance
104        method?](#subsection34)
105
106      - [What is $type?](#subsection35)
107
108      - [What is $self?](#subsection36)
109
110      - [What is $selfns?](#subsection37)
111
112      - [What is $win?](#subsection38)
113
114      - [How do I pass an instance method as a callback?](#subsection39)
115
116      - [How do I delegate instance methods to a component?](#subsection40)
117
118  - [INSTANCE VARIABLES](#section6)
119
120      - [What is an instance variable?](#subsection41)
121
122      - [How is a scalar instance variable defined?](#subsection42)
123
124      - [How is an array instance variable defined?](#subsection43)
125
126      - [What happens if I don't initialize an instance
127        variable?](#subsection44)
128
129      - [Are there any limitations on instance variable
130        names?](#subsection45)
131
132      - [Do I need to declare my instance variables in my
133        methods?](#subsection46)
134
135      - [How do I pass an instance variable's name to another
136        object?](#subsection47)
137
138      - [How do I make an instance variable public?](#subsection48)
139
140  - [OPTIONS](#section7)
141
142      - [What is an option?](#subsection49)
143
144      - [How do I define an option?](#subsection50)
145
146      - [How can a client set options at object creation?](#subsection51)
147
148      - [How can a client retrieve an option's value?](#subsection52)
149
150      - [How can a client set options after object
151        creation?](#subsection53)
152
153      - [How should an instance method access an option
154        value?](#subsection54)
155
156      - [How can I make an option read\-only?](#subsection55)
157
158      - [How can I catch accesses to an option's value?](#subsection56)
159
160      - [What is a \-cgetmethod?](#subsection57)
161
162      - [How can I catch changes to an option's value?](#subsection58)
163
164      - [What is a \-configuremethod?](#subsection59)
165
166      - [How can I validate an option's value?](#subsection60)
167
168      - [What is a \-validatemethod?](#subsection61)
169
170  - [TYPE VARIABLES](#section8)
171
172      - [What is a type variable?](#subsection62)
173
174      - [How is a scalar type variable defined?](#subsection63)
175
176      - [How is an array\-valued type variable defined?](#subsection64)
177
178      - [What happens if I don't initialize a type
179        variable?](#subsection65)
180
181      - [Are there any limitations on type variable names?](#subsection66)
182
183      - [Do I need to declare my type variables in my
184        methods?](#subsection67)
185
186      - [How do I pass a type variable's name to another
187        object?](#subsection68)
188
189      - [How do I make a type variable public?](#subsection69)
190
191  - [TYPE METHODS](#section9)
192
193      - [What is a type method?](#subsection70)
194
195      - [How do I define a type method?](#subsection71)
196
197      - [How does a client call a type method?](#subsection72)
198
199      - [Are there any limitations on type method names?](#subsection73)
200
201      - [How do I make a type method private?](#subsection74)
202
203      - [Are there any limitations on type method
204        arguments?](#subsection75)
205
206      - [How does an instance or type method call a type
207        method?](#subsection76)
208
209      - [How do I pass a type method as a callback?](#subsection77)
210
211      - [Can type methods be hierarchical?](#subsection78)
212
213  - [PROCS](#section10)
214
215      - [What is a proc?](#subsection79)
216
217      - [How do I define a proc?](#subsection80)
218
219      - [Are there any limitations on proc names?](#subsection81)
220
221      - [How does a method call a proc?](#subsection82)
222
223      - [How can I pass a proc to another object as a
224        callback?](#subsection83)
225
226  - [TYPE CONSTRUCTORS](#section11)
227
228      - [What is a type constructor?](#subsection84)
229
230      - [How do I define a type constructor?](#subsection85)
231
232  - [CONSTRUCTORS](#section12)
233
234      - [What is a constructor?](#subsection86)
235
236      - [How do I define a constructor?](#subsection87)
237
238      - [What does the default constructor do?](#subsection88)
239
240      - [Can I choose a different set of arguments for the
241        constructor?](#subsection89)
242
243      - [Are there any limitations on constructor
244        arguments?](#subsection90)
245
246      - [Is there anything special about writing the
247        constructor?](#subsection91)
248
249  - [DESTRUCTORS](#section13)
250
251      - [What is a destructor?](#subsection92)
252
253      - [How do I define a destructor?](#subsection93)
254
255      - [Are there any limitations on destructor arguments?](#subsection94)
256
257      - [What implicit arguments are passed to the
258        destructor?](#subsection95)
259
260      - [Must components be destroyed explicitly?](#subsection96)
261
262      - [Is there any special about writing a destructor?](#subsection97)
263
264  - [COMPONENTS](#section14)
265
266      - [What is a component?](#subsection98)
267
268      - [How do I declare a component?](#subsection99)
269
270      - [How is a component named?](#subsection100)
271
272      - [Are there any limitations on component names?](#subsection101)
273
274      - [What is an owned component?](#subsection102)
275
276      - [What does the install command do?](#subsection103)
277
278      - [Must owned components be created in the
279        constructor?](#subsection104)
280
281      - [Are there any limitations on component object
282        names?](#subsection105)
283
284      - [Must I destroy the components I own?](#subsection106)
285
286      - [Can I expose a component's object command as part of my
287        interface?](#subsection107)
288
289      - [How do I expose a component's object command?](#subsection108)
290
291  - [TYPE COMPONENTS](#section15)
292
293      - [What is a type component?](#subsection109)
294
295      - [How do I declare a type component?](#subsection110)
296
297      - [How do I install a type component?](#subsection111)
298
299      - [Are there any limitations on type component
300        names?](#subsection112)
301
302  - [DELEGATION](#section16)
303
304      - [What is delegation?](#subsection113)
305
306      - [How can I delegate a method to a component
307        object?](#subsection114)
308
309      - [Can I delegate to a method with a different name?](#subsection115)
310
311      - [Can I delegate to a method with additional
312        arguments?](#subsection116)
313
314      - [Can I delegate a method to something other than an
315        object?](#subsection117)
316
317      - [How can I delegate a method to a type component
318        object?](#subsection118)
319
320      - [How can I delegate a type method to a type component
321        object?](#subsection119)
322
323      - [How can I delegate an option to a component
324        object?](#subsection120)
325
326      - [Can I delegate to an option with a different
327        name?](#subsection121)
328
329      - [How can I delegate any unrecognized method or option to a component
330        object?](#subsection122)
331
332      - [How can I delegate all but certain methods or options to a
333        component?](#subsection123)
334
335      - [Can a hierarchical method be delegated?](#subsection124)
336
337  - [WIDGETS](#section17)
338
339      - [What is a snit::widget?](#subsection125)
340
341      - [How do I define a snit::widget?](#subsection126)
342
343      - [How do snit::widgets differ from snit::types?](#subsection127)
344
345      - [What is a hull component?](#subsection128)
346
347      - [How can I set the hull type for a snit::widget?](#subsection129)
348
349      - [How should I name widgets which are components of a
350        snit::widget?](#subsection130)
351
352  - [WIDGET ADAPTORS](#section18)
353
354      - [What is a snit::widgetadaptor?](#subsection131)
355
356      - [How do I define a snit::widgetadaptor?](#subsection132)
357
358      - [Can I adapt a widget created elsewhere in the
359        program?](#subsection133)
360
361      - [Can I adapt another megawidget?](#subsection134)
362
363  - [THE TK OPTION DATABASE](#section19)
364
365      - [What is the Tk option database?](#subsection135)
366
367      - [Do snit::types use the Tk option database?](#subsection136)
368
369      - [What is my snit::widget's widget class?](#subsection137)
370
371      - [What is my snit::widgetadaptor's widget class?](#subsection138)
372
373      - [What are option resource and class names?](#subsection139)
374
375      - [What are the resource and class names for my megawidget's
376        options?](#subsection140)
377
378      - [How does Snit initialize my megawidget's locally\-defined
379        options?](#subsection141)
380
381      - [How does Snit initialize delegated options?](#subsection142)
382
383      - [How does Snit initialize options delegated to the
384        hull?](#subsection143)
385
386      - [How does Snit initialize options delegated to other
387        components?](#subsection144)
388
389      - [What happens if I install a non\-widget as a component of
390        widget?](#subsection145)
391
392  - [ENSEMBLE COMMANDS](#section20)
393
394      - [What is an ensemble command?](#subsection146)
395
396      - [How can I create an ensemble command using Snit?](#subsection147)
397
398      - [How can I create an ensemble command using an instance of a
399        snit::type?](#subsection148)
400
401      - [How can I create an ensemble command using a
402        snit::type?](#subsection149)
403
404  - [PRAGMAS](#section21)
405
406      - [What is a pragma?](#subsection150)
407
408      - [How do I set a pragma?](#subsection151)
409
410      - [How can I get rid of the "info" type method?](#subsection152)
411
412      - [How can I get rid of the "destroy" type method?](#subsection153)
413
414      - [How can I get rid of the "create" type method?](#subsection154)
415
416      - [How can I get rid of type methods altogether?](#subsection155)
417
418      - [Why can't I create an object that replaces an old object with the same
419        name?](#subsection156)
420
421      - [How can I make my simple type run faster?](#subsection157)
422
423  - [MACROS](#section22)
424
425      - [What is a macro?](#subsection158)
426
427      - [What are macros good for?](#subsection159)
428
429      - [How do I do conditional compilation?](#subsection160)
430
431      - [How do I define new type definition syntax?](#subsection161)
432
433      - [Are there are restrictions on macro names?](#subsection162)
434
435  - [Bugs, Ideas, Feedback](#section23)
436
437  - [Keywords](#keywords)
438
439  - [Category](#category)
440
441  - [Copyright](#copyright)
442
443# <a name='description'></a>DESCRIPTION
444
445# <a name='section2'></a>OVERVIEW
446
447## <a name='subsection1'></a>What is this document?
448
449This is an atypical FAQ list, in that few of the questions are frequently asked\.
450Rather, these are the questions I think a newcomer to Snit should be asking\.
451This file is not a complete reference to Snit, however; that information is in
452the __[snit](snit\.md)__ man page\.
453
454## <a name='subsection2'></a>What is Snit?
455
456Snit is a framework for defining abstract data types and megawidgets in pure
457Tcl\. The name "Snit" stands for "Snit's Not Incr Tcl", signifying that Snit
458takes a different approach to defining objects than does Incr Tcl, the best
459known object framework for Tcl\. Had I realized that Snit would become at all
460popular, I'd probably have chosen something else\.
461
462The primary purpose of Snit is to be *object glue*\-\-to help you compose
463diverse objects from diverse sources into types and megawidgets with clean,
464convenient interfaces so that you can more easily build your application\.
465
466Snit isn't about theoretical purity or minimalist design; it's about being able
467to do powerful things easily and consistently without having to think about
468them\-\-so that you can concentrate on building your application\.
469
470Snit isn't about implementing thousands of nearly identical carefully\-specified
471lightweight thingamajigs\-\-not as individual Snit objects\. Traditional Tcl
472methods will be much faster, and not much more complicated\. But Snit *is*
473about implementing a clean interface to manage a collection of thousands of
474nearly identical carefully\-specified lightweight thingamajigs \(e\.g\., think of
475the text widget and text tags, or the canvas widget and canvas objects\)\. Snit
476lets you hide the details of just how those thingamajigs are stored\-\-so that you
477can ignore it, and concentrate on building your application\.
478
479Snit isn't a way of life, a silver bullet, or the Fountain of Youth\. It's just a
480way of managing complexity\-\-and of managing some of the complexity of managing
481complexity\-\-so that you can concentrate on building your application\.
482
483## <a name='subsection3'></a>What version of Tcl does Snit require?
484
485Snit 1\.3 requires Tcl 8\.3 or later; Snit 2\.2 requires Tcl 8\.5 or later\. See
486[SNIT VERSIONS](#section3) for the differences between Snit 1\.3 and Snit
4872\.2\.
488
489## <a name='subsection4'></a>Where can I download Snit?
490
491Snit is part of Tcllib, the standard Tcl library, so you might already have it\.
492It's also available at the Snit Home Page,
493[http://www\.wjduquette\.com/snit](http://www\.wjduquette\.com/snit)\.
494
495## <a name='subsection5'></a>What are Snit's goals?
496
497  - A Snit object should be at least as efficient as a hand\-coded Tcl object
498    \(see
499    [http://www\.wjduquette\.com/tcl/objects\.html](http://www\.wjduquette\.com/tcl/objects\.html)\)\.
500
501  - The fact that Snit was used in an object's implementation should be
502    transparent \(and irrelevant\) to clients of that object\.
503
504  - Snit should be able to encapsulate objects from other sources, particularly
505    Tk widgets\.
506
507  - Snit megawidgets should be \(to the extent possible\) indistinguishable in
508    interface from Tk widgets\.
509
510  - Snit should be Tclish\-\-that is, rather than trying to emulate C\+\+,
511    Smalltalk, or anything else, it should try to emulate Tcl itself\.
512
513  - It should have a simple, easy\-to\-use, easy\-to\-remember syntax\.
514
515## <a name='subsection6'></a>How is Snit different from other OO frameworks?
516
517Snit is unique among Tcl object systems in that it is based not on inheritance
518but on delegation\. Object systems based on inheritance only allow you to inherit
519from classes defined using the same system, and that's a shame\. In Tcl, an
520object is anything that acts like an object; it shouldn't matter how the object
521was implemented\. I designed Snit to help me build applications out of the
522materials at hand; thus, Snit is designed to be able to incorporate and build on
523any object, whether it's a hand\-coded object, a Tk widget, an Incr Tcl object, a
524BWidget or almost anything else\.
525
526Note that you can achieve the effect of inheritance using
527[COMPONENTS](#section14) and [DELEGATION](#section16)\-\-and you can
528inherit from anything that looks like a Tcl object\.
529
530## <a name='subsection7'></a>What can I do with Snit?
531
532Using Snit, a programmer can:
533
534  - Create abstract data types and Tk megawidgets\.
535
536  - Define instance variables, type variables, and Tk\-style options\.
537
538  - Define constructors, destructors, instance methods, type methods, procs\.
539
540  - Assemble a type out of component types\. Instance methods and options can be
541    delegated to the component types automatically\.
542
543# <a name='section3'></a>SNIT VERSIONS
544
545## <a name='subsection8'></a>Which version of Snit should I use?
546
547The current Snit distribution includes two versions, Snit 1\.3 and Snit 2\.2\. The
548reason that both are included is that Snit 2\.2 takes advantage of a number of
549new features of Tcl 8\.5 to improve run\-time efficiency; as a side\-effect, the
550ugliness of Snit's error messages and stack traces has been reduced
551considerably\. The cost of using Snit 2\.2, of course, is that you must target Tcl
5528\.5\.
553
554Snit 1\.3, on the other hand, lacks Snit 2\.2's optimizations, but requires only
555Tcl 8\.3 and later\.
556
557In short, if you're targetting Tcl 8\.3 or 8\.4 you should use Snit 1\.3\. If you
558can afford to target Tcl 8\.5, you should definitely use Snit 2\.2\. If you will be
559targetting both, you can use Snit 1\.3 exclusively, or \(if your code is
560unaffected by the minor incompatibilities between the two versions\) you can use
561Snit 1\.3 for Tcl 8\.4 and Snit 2\.2 for Tcl 8\.5\.
562
563## <a name='subsection9'></a>How do I select the version of Snit I want to use?
564
565To always use Snit 1\.3 \(or a later version of Snit 1\.x\), invoke Snit as follows:
566
567    package require snit 1.3
568
569To always use Snit 2\.2 \(or a later version of Snit 2\.x\), say this instead:
570
571    package require snit 2.2
572
573Note that if you request Snit 2\.2 explicitly, your application will halt with
574Tcl 8\.4, since Snit 2\.2 is unavailable for Tcl 8\.4\.
575
576If you wish your application to always use the latest available version of Snit,
577don't specify a version number:
578
579    package require snit
580
581Tcl will find and load the latest version that's available relative to the
582version of Tcl being used\. In this case, be careful to avoid using any
583incompatible features\.
584
585## <a name='subsection10'></a>How are Snit 1\.3 and Snit 2\.2 incompatible?
586
587To the extent possible, Snit 2\.2 is intended to be a drop\-in replacement for
588Snit 1\.3\. Unfortunately, some incompatibilities were inevitable because Snit 2\.2
589uses Tcl 8\.5's new __namespace ensemble__ mechanism to implement subcommand
590dispatch\. This approach is much faster than the mechanism used in Snit 1\.3, and
591also results in much better error messages; however, it also places new
592constraints on the implementation\.
593
594There are four specific incompatibilities between Snit 1\.3 and Snit 2\.2\.
595
596  - Snit 1\.3 supports implicit naming of objects\. Suppose you define a new
597    __snit::type__ called __dog__\. You can create instances of
598    __dog__ in three ways:
599
600    dog spot               ;# Explicit naming
601    set obj1 [dog %AUTO%]  ;# Automatic naming
602    set obj2 [dog]         ;# Implicit naming
603
604    In Snit 2\.2, type commands are defined using the __namespace ensemble__
605    mechanism; and __namespace ensemble__ doesn't allow an ensemble command
606    to be called without a subcommand\. In short, using __namespace
607    ensemble__ there's no way to support implicit naming\.
608
609    All is not lost, however\. If the type has no type methods, then the type
610    command is a simple command rather than an ensemble, and __namespace
611    ensemble__ is not used\. In this case, implicit naming is still possible\.
612
613    In short, you can have implicit naming if you're willing to do without type
614    methods \(including the standard type methods, like __$type info__\)\. To
615    do so, use the __\-hastypemethods__ pragma:
616
617    pragma -hastypemethods 0
618
619  - Hierarchical methods and type methods are implemented differently in Snit
620    2\.2\.
621
622    A hierarchical method is an instance method which has subcommands; these
623    subcommands are themselves methods\. The Tk text widget's __tag__ command
624    and its subcommands are examples of hierarchical methods\. You can implement
625    such subcommands in Snit simply by including multiple words in the method
626    names:
627
628    method {tag configure} {tag args} { ... }
629
630    method {tag cget} {tag option} {...}
631
632    Here we've implicitly defined a __tag__ method which has two
633    subcommands, __configure__ and __cget__\.
634
635    In Snit 1\.3, hierarchical methods could be called in two ways:
636
637    $obj tag cget -myoption      ;# The good way
638    $obj {tag cget} -myoption    ;# The weird way
639
640    In the second call, we see that a hierarchical method or type method is
641    simply one whose name contains multiple words\.
642
643    In Snit 2\.2 this is no longer the case, and the "weird" way of calling
644    hierarchical methods and type methods no longer works\.
645
646  - The third incompatibility derives from the second\. In Snit 1\.3, hierarchical
647    methods were also simply methods whose name contains multiple words\. As a
648    result, __$obj info methods__ returned the full names of all
649    hierarchical methods\. In the example above, the list returned by __$obj
650    info methods__ would include __tag configure__ and __tag cget__
651    but not __tag__, since __tag__ is defined only implicitly\.
652
653    In Snit 2\.2, hierarchical methods and type methods are no longer simply ones
654    whose name contains multiple words; in the above example, the list returned
655    by __$obj info methods__ would include __tag__ but not __tag
656    configure__ or __tag cget__\.
657
658  - The fourth incompatibility is due to a new feature\. Snit 2\.2 uses the new
659    __namespace path__ command so that a type's code can call any command
660    defined in the type's parent namespace without qualification or importation\.
661    For example, suppose you have a package called __mypackage__ which
662    defines a number of commands including a type, __::mypackage::mytype__\.
663    Thanks to __namespace path__, the type's code can call any of the other
664    commands defined in __::mypackage::__\.
665
666    This is extremely convenient\. However, it also means that commands defined
667    in the parent namespace, __::mypackage::__ can block the type's access
668    to identically named commands in the global namespace\. This can lead to
669    bugs\. For example, Tcllib includes a type called __::tie::std::file__\.
670    This type's code calls the standard
671    __[file](\.\./\.\./\.\./\.\./index\.md\#file)__ command\. When run with Snit
672    2\.2, the code broke\-\- the type's command, __::tie::std::file__, is
673    itself a command in the type's parent namespace, and so instead of calling
674    the standard __[file](\.\./\.\./\.\./\.\./index\.md\#file)__ command, the type
675    found itself calling itself\.
676
677## <a name='subsection11'></a>Are there other differences between Snit 1\.x and Snit 2\.2?
678
679Yes\.
680
681  - Method dispatch is considerably faster\.
682
683  - Many error messages and stack traces are cleaner\.
684
685  - The __\-simpledispatch__ pragma is obsolete, and ignored if present\. In
686    Snit 1\.x, __\-simpledispatch__ substitutes a faster mechanism for method
687    dispatch, at the cost of losing certain features\. Snit 2\.2 method dispatch
688    is faster still in all cases, so __\-simpledispatch__ is no longer
689    needed\.
690
691  - In Snit 2\.2, a type's code \(methods, type methods, etc\.\) can call commands
692    from the type's parent namespace without qualifying or importing them, i\.e\.,
693    type __::parentns::mytype__'s code can call __::parentns::someproc__
694    as just __someproc__\.
695
696    This is extremely useful when a type is defined as part of a larger package,
697    and shares a parent namespace with the rest of the package; it means that
698    the type can call other commands defined by the package without any extra
699    work\.
700
701    This feature depends on the new Tcl 8\.5 __namespace path__ command,
702    which is why it hasn't been implemented for V1\.x\. V1\.x code can achieve
703    something similar by placing
704
705    namespace import [namespace parent]::*
706
707    in a type constructor\. This is less useful, however, as it picks up only
708    those commands which have already been exported by the parent namespace at
709    the time the type is defined\.
710
711# <a name='section4'></a>OBJECTS
712
713## <a name='subsection12'></a>What is an object?
714
715A full description of object\-oriented programming is beyond the scope of this
716FAQ, obviously\. In simple terms, an object is an instance of an abstract data
717type\-\-a coherent bundle of code and data\. There are many ways to represent
718objects in Tcl/Tk; the best known examples are the Tk widgets\.
719
720A Tk widget is an object; it is represented by a Tcl command\. The object's
721methods are subcommands of the Tcl command\. The object's properties are options
722accessed using the __configure__ and __cget__ methods\. Snit uses the
723same conventions as Tk widgets do\.
724
725## <a name='subsection13'></a>What is an abstract data type?
726
727In computer science terms, an abstract data type is a complex data structure
728along with a set of operations\-\-a stack, a queue, a binary tree, etc\-\-that is to
729say, in modern terms, an object\. In systems that include some form of
730inheritance the word *[class](\.\./\.\./\.\./\.\./index\.md\#class)* is usually used
731instead of *abstract data type*, but as Snit doesn't implement inheritance as
732it's ordinarily understood the older term seems more appropriate\. Sometimes this
733is called *object\-based* programming as opposed to object\-oriented
734programming\. Note that you can easily create the effect of inheritance using
735[COMPONENTS](#section14) and [DELEGATION](#section16)\.
736
737In Snit, as in Tk, a *[type](\.\./\.\./\.\./\.\./index\.md\#type)* is a command that
738creates instances \-\- objects \-\- which belong to the type\. Most types define some
739number of *options* which can be set at creation time, and usually can be
740changed later\.
741
742Further, an *instance* is also a Tcl command\-\-a command that gives access to
743the operations which are defined for that abstract data type\. Conventionally,
744the operations are defined as subcommands of the instance command\. For example,
745to insert text into a Tk text widget, you use the text widget's __insert__
746subcommand:
747
748    # Create a text widget and insert some text in it.
749    text .mytext -width 80 -height 24
750    .mytext insert end "Howdy!"
751
752In this example, __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ is the
753*[type](\.\./\.\./\.\./\.\./index\.md\#type)* command and __\.mytext__ is the
754*instance* command\.
755
756In Snit, object subcommands are generally called [INSTANCE
757METHODS](#section5)\.
758
759## <a name='subsection14'></a>What kinds of abstract data types does Snit provide?
760
761Snit allows you to define three kinds of abstract data type:
762
763  - __snit::type__
764
765  - __snit::widget__
766
767  - __snit::widgetadaptor__
768
769## <a name='subsection15'></a>What is a snit::type?
770
771A __snit::type__ is a non\-GUI abstract data type, e\.g\., a stack or a queue\.
772__snit::type__s are defined using the __snit::type__ command\. For
773example, if you were designing a kennel management system for a dog breeder,
774you'd need a dog type\.
775
776    % snit::type dog {
777        # ...
778    }
779    ::dog
780    %
781
782This definition defines a new command \(__::dog__, in this case\) that can be
783used to define dog objects\.
784
785An instance of a __snit::type__ can have [INSTANCE METHODS](#section5),
786[INSTANCE VARIABLES](#section6), [OPTIONS](#section7), and
787[COMPONENTS](#section14)\. The type itself can have [TYPE
788METHODS](#section9), [TYPE VARIABLES](#section8), [TYPE
789COMPONENTS](#section15), and [PROCS](#section10)\.
790
791## <a name='subsection16'></a>What is a snit::widget?, the short story
792
793A __snit::widget__ is a Tk megawidget built using Snit; it is very similar
794to a __snit::type__\. See [WIDGETS](#section17)\.
795
796## <a name='subsection17'></a>What is a snit::widgetadaptor?, the short story
797
798A __snit::widgetadaptor__ uses Snit to wrap an existing widget type \(e\.g\., a
799Tk label\), modifying its interface to a lesser or greater extent\. It is very
800similar to a __snit::widget__\. See [WIDGET ADAPTORS](#section18)\.
801
802## <a name='subsection18'></a>How do I create an instance of a snit::type?
803
804You create an instance of a __snit::type__ by passing the new instance's
805name to the type's create method\. In the following example, we create a
806__dog__ object called __spot__\.
807
808    % snit::type dog {
809        # ....
810    }
811    ::dog
812    % dog create spot
813    ::spot
814    %
815
816In general, the __create__ method name can be omitted so long as the
817instance name doesn't conflict with any defined [TYPE METHODS](#section9)\.
818\(See [TYPE COMPONENTS](#section15) for the special case in which this
819doesn't work\.\) So the following example is identical to the previous example:
820
821    % snit::type dog {
822        # ....
823    }
824    ::dog
825    % dog spot
826    ::spot
827    %
828
829This document generally uses the shorter form\.
830
831If the __dog__ type defines [OPTIONS](#section7), these can usually be
832given defaults at creation time:
833
834    % snit::type dog {
835        option -breed mongrel
836        option -color brown
837
838        method bark {} { return "$self barks." }
839    }
840    ::dog
841    % dog create spot -breed dalmation -color spotted
842    ::spot
843    % spot cget -breed
844    dalmation
845    % spot cget -color
846    spotted
847    %
848
849Once created, the instance name now names a new Tcl command that is used to
850manipulate the object\. For example, the following code makes the dog bark:
851
852    % spot bark
853    ::spot barks.
854    %
855
856## <a name='subsection19'></a>How do I refer to an object indirectly?
857
858Some programmers prefer to save the object name in a variable, and reference it
859that way\. For example,
860
861    % snit::type dog { ... }
862    ::dog
863    % set d [dog spot -breed dalmation -color spotted]
864    ::spot
865    % $d cget -breed
866    dalmation
867    % $d bark
868    ::spot barks.
869    %
870
871If you prefer this style, you might prefer to have Snit generate the instance's
872name automatically\.
873
874## <a name='subsection20'></a>How can I generate the object name automatically?
875
876If you'd like Snit to generate an object name for you, use the __%AUTO%__
877keyword as the requested name:
878
879    % snit::type dog { ... }
880    ::dog
881    % set d [dog %AUTO%]
882    ::dog2
883    % $d bark
884    ::dog2 barks.
885    %
886
887The __%AUTO%__ keyword can be embedded in a longer string:
888
889    % set d [dog obj_%AUTO%]
890    ::obj_dog4
891    % $d bark
892    ::obj_dog4 barks.
893    %
894
895## <a name='subsection21'></a>Can types be renamed?
896
897Tcl's __rename__ command renames other commands\. It's a common technique in
898Tcl to modify an existing command by renaming it and defining a new command with
899the original name; the new command usually calls the renamed command\.
900
901__snit::type__ commands, however, should never be renamed; to do so breaks
902the connection between the type and its objects\.
903
904## <a name='subsection22'></a>Can objects be renamed?
905
906Tcl's __rename__ command renames other commands\. It's a common technique in
907Tcl to modify an existing command by renaming it and defining a new command with
908the original name; the new command usually calls the renamed command\.
909
910All Snit objects \(including *widgets* and *widgetadaptors*\) can be renamed,
911though this flexibility has some consequences:
912
913  - In an instance method, the implicit argument __self__ will always
914    contain the object's current name, so instance methods can always call other
915    instance methods using __$self__\.
916
917  - If the object is renamed, however, then __$self__'s value will change\.
918    Therefore, don't use __$self__ for anything that will break if
919    __$self__ changes\. For example, don't pass a callback command to another
920    object like this:
921
922    .btn configure -command [list $self ButtonPress]
923
924    You'll get an error if __\.btn__ calls your command after your object is
925    renamed\.
926
927  - Instead, your object should define its callback command like this:
928
929    .btn configure -command [mymethod ButtonPress]
930
931    The __mymethod__ command returns code that will call the desired method
932    safely; the caller of the callback can add additional arguments to the end
933    of the command as usual\.
934
935  - Every object has a private namespace; the name of this namespace is
936    available in method bodies, etc\., as the value of the implicit argument
937    __selfns__\. This value is constant for the life of the object\. Use
938    __$selfns__ instead of __$self__ if you need a unique token to
939    identify the object\.
940
941  - When a __snit::widget__'s instance command is renamed, its Tk window
942    name remains the same \-\- and is still extremely important\. Consequently, the
943    Tk window name is available in method bodies as the value of the implicit
944    argument __win__\. This value is constant for the life of the object\.
945    When creating child windows, it's best to use __$win\.child__ rather than
946    __$self\.child__ as the name of the child window\.
947
948## <a name='subsection23'></a>How do I destroy a Snit object?
949
950Any Snit object of any type can be destroyed by renaming it to the empty string
951using the Tcl __rename__ command\.
952
953Snit megawidgets \(i\.e\., instances of __snit::widget__ and
954__snit::widgetadaptor__\) can be destroyed like any other widget: by using
955the Tk __destroy__ command on the widget or on one of its ancestors in the
956window hierarchy\.
957
958Every instance of a __snit::type__ has a __destroy__ method:
959
960    % snit::type dog { ... }
961    ::dog
962    % dog spot
963    ::spot
964    % spot bark
965    ::spot barks.
966    % spot destroy
967    % spot barks
968    invalid command name "spot"
969    %
970
971Finally, every Snit type has a type method called __destroy__; calling it
972destroys the type and all of its instances:
973
974    % snit::type dog { ... }
975    ::dog
976    % dog spot
977    ::spot
978    % spot bark
979    ::spot barks.
980    % dog destroy
981    % spot bark
982    invalid command name "spot"
983    % dog fido
984    invalid command name "dog"
985    %
986
987# <a name='section5'></a>INSTANCE METHODS
988
989## <a name='subsection24'></a>What is an instance method?
990
991An instance method is a procedure associated with a specific object and called
992as a subcommand of the object's command\. It is given free access to all of the
993object's type variables, instance variables, and so forth\.
994
995## <a name='subsection25'></a>How do I define an instance method?
996
997Instance methods are defined in the type definition using the
998__[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement\. Consider the
999following code that might be used to add dogs to a computer simulation:
1000
1001    % snit::type dog {
1002        method bark {} {
1003            return "$self barks."
1004        }
1005
1006        method chase {thing} {
1007            return "$self chases $thing."
1008        }
1009    }
1010    ::dog
1011    %
1012
1013A dog can bark, and it can chase things\.
1014
1015The __[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement looks just like
1016a normal Tcl __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, except that it
1017appears in a __snit::type__ definition\. Notice that every instance method
1018gets an implicit argument called __self__; this argument contains the
1019object's name\. \(There's more on implicit method arguments below\.\)
1020
1021## <a name='subsection26'></a>How does a client call an instance method?
1022
1023The method name becomes a subcommand of the object\. For example, let's put a
1024simulated dog through its paces:
1025
1026    % dog spot
1027    ::spot
1028    % spot bark
1029    ::spot barks.
1030    % spot chase cat
1031    ::spot chases cat.
1032    %
1033
1034## <a name='subsection27'></a>How does an instance method call another instance method?
1035
1036If method A needs to call method B on the same object, it does so just as a
1037client does: it calls method B as a subcommand of the object itself, using the
1038object name stored in the implicit argument __self__\.
1039
1040Suppose, for example, that our dogs never chase anything without barking at
1041them:
1042
1043    % snit::type dog {
1044        method bark {} {
1045            return "$self barks."
1046        }
1047
1048        method chase {thing} {
1049            return "$self chases $thing.  [$self bark]"
1050        }
1051    }
1052    ::dog
1053    % dog spot
1054    ::spot
1055    % spot bark
1056    ::spot barks.
1057    % spot chase cat
1058    ::spot chases cat.  ::spot barks.
1059    %
1060
1061## <a name='subsection28'></a>Are there any limitations on instance method names?
1062
1063Not really, so long as you avoid the standard instance method names:
1064__configure__, __configurelist__, __cget__, __destroy__, and
1065__info__\. Also, method names consisting of multiple words define
1066hierarchical methods\.
1067
1068## <a name='subsection29'></a>What is a hierarchical method?
1069
1070An object's methods are subcommands of the object's instance command\.
1071Hierarchical methods allow an object's methods to have subcommands of their own;
1072and these can in turn have subcommands, and so on\. This allows the programmer to
1073define a tree\-shaped command structure, such as is used by many of the Tk
1074widgets\-\-the subcommands of the Tk __[text](\.\./\.\./\.\./\.\./index\.md\#text)__
1075widget's __tag__ method are hierarchical methods\.
1076
1077## <a name='subsection30'></a>How do I define a hierarchical method?
1078
1079Define methods whose names consist of multiple words\. These words define the
1080hierarchy implicitly\. For example, the following code defines a __tag__
1081method with subcommands __cget__ and __configure__:
1082
1083    snit::widget mytext {
1084        method {tag configure} {tag args} { ... }
1085
1086        method {tag cget} {tag option} {...}
1087    }
1088
1089Note that there is no explicit definition for the __tag__ method; it is
1090implicit in the definition of __tag configure__ and __tag cget__\. If you
1091tried to define __tag__ explicitly in this example, you'd get an error\.
1092
1093## <a name='subsection31'></a>How do I call hierarchical methods?
1094
1095As subcommands of subcommands\.
1096
1097    % mytext .text
1098    .text
1099    % .text tag configure redtext -foreground red -background black
1100    % .text tag cget redtext -foreground
1101    red
1102    %
1103
1104## <a name='subsection32'></a>How do I make an instance method private?
1105
1106It's often useful to define private methods, that is, instance methods intended
1107to be called only by other methods of the same object\.
1108
1109Snit doesn't implement any access control on instance methods, so all methods
1110are *de facto* public\. Conventionally, though, the names of public methods
1111begin with a lower\-case letter, and the names of private methods begin with an
1112upper\-case letter\.
1113
1114For example, suppose our simulated dogs only bark in response to other stimuli;
1115they never bark just for fun\. So the __bark__ method becomes __Bark__ to
1116indicate that it is private:
1117
1118    % snit::type dog {
1119        # Private by convention: begins with uppercase letter.
1120        method Bark {} {
1121            return "$self barks."
1122        }
1123
1124        method chase {thing} {
1125            return "$self chases $thing. [$self Bark]"
1126        }
1127    }
1128    ::dog
1129    % dog fido
1130    ::fido
1131    % fido chase cat
1132    ::fido chases cat. ::fido barks.
1133    %
1134
1135## <a name='subsection33'></a>Are there any limitations on instance method arguments?
1136
1137Method argument lists are defined just like normal Tcl
1138__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ argument lists; in particular,
1139they can include arguments with default values and the __args__ argument\.
1140
1141However, every method also has a number of implicit arguments provided by Snit
1142in addition to those explicitly defined\. The names of these implicit arguments
1143may not used to name explicit arguments\.
1144
1145## <a name='subsection34'></a>What implicit arguments are passed to each instance method?
1146
1147The arguments implicitly passed to every method are __type__,
1148__selfns__, __win__, and __self__\.
1149
1150## <a name='subsection35'></a>What is $type?
1151
1152The implicit argument __type__ contains the fully qualified name of the
1153object's type:
1154
1155    % snit::type thing {
1156        method mytype {} {
1157            return $type
1158        }
1159    }
1160    ::thing
1161    % thing something
1162    ::something
1163    % something mytype
1164    ::thing
1165    %
1166
1167## <a name='subsection36'></a>What is $self?
1168
1169The implicit argument __self__ contains the object's fully qualified name\.
1170
1171If the object's command is renamed, then __$self__ will change to match in
1172subsequent calls\. Thus, your code should not assume that __$self__ is
1173constant unless you know for sure that the object will never be renamed\.
1174
1175    % snit::type thing {
1176        method myself {} {
1177            return $self
1178        }
1179    }
1180    ::thing
1181    % thing mutt
1182    ::mutt
1183    % mutt myself
1184    ::mutt
1185    % rename mutt jeff
1186    % jeff myself
1187    ::jeff
1188    %
1189
1190## <a name='subsection37'></a>What is $selfns?
1191
1192Each Snit object has a private namespace in which to store its [INSTANCE
1193VARIABLES](#section6) and [OPTIONS](#section7)\. The implicit argument
1194__selfns__ contains the name of this namespace; its value never changes, and
1195is constant for the life of the object, even if the object's name changes:
1196
1197    % snit::type thing {
1198        method myNameSpace {} {
1199            return $selfns
1200        }
1201    }
1202    ::thing
1203    % thing jeff
1204    ::jeff
1205    % jeff myNameSpace
1206    ::thing::Snit_inst3
1207    % rename jeff mutt
1208    % mutt myNameSpace
1209    ::thing::Snit_inst3
1210    %
1211
1212The above example reveals how Snit names an instance's private namespace;
1213however, you should not write code that depends on the specific naming
1214convention, as it might change in future releases\.
1215
1216## <a name='subsection38'></a>What is $win?
1217
1218The implicit argument __win__ is defined for all Snit methods, though it
1219really makes sense only for those of [WIDGETS](#section17) and [WIDGET
1220ADAPTORS](#section18)\. __$win__ is simply the original name of the
1221object, whether it's been renamed or not\. For widgets and widgetadaptors, it is
1222also therefore the name of a Tk window\.
1223
1224When a __snit::widgetadaptor__ is used to modify the interface of a widget
1225or megawidget, it must rename the widget's original command and replace it with
1226its own\.
1227
1228Thus, using __win__ whenever the Tk window name is called for means that a
1229__snit::widget__ or __snit::widgetadaptor__ can be adapted by a
1230__snit::widgetadaptor__\. See [WIDGETS](#section17) for more
1231information\.
1232
1233## <a name='subsection39'></a>How do I pass an instance method as a callback?
1234
1235It depends on the context\.
1236
1237Suppose in my application I have a __dog__ object named __fido__, and I
1238want __fido__ to bark when a Tk button called __\.bark__ is pressed\. In
1239this case, I create the callback command in the usual way, using
1240__[list](\.\./\.\./\.\./\.\./index\.md\#list)__:
1241
1242    button .bark -text "Bark!" -command [list fido bark]
1243
1244In typical Tcl style, we use a callback to hook two independent components
1245together\. But suppose that the __dog__ object has a graphical interface and
1246owns the button itself? In this case, the __dog__ must pass one of its own
1247instance methods to the button it owns\. The obvious thing to do is this:
1248
1249    % snit::widget dog {
1250        constructor {args} {
1251            #...
1252            button $win.barkbtn -text "Bark!" -command [list $self bark]
1253            #...
1254        }
1255    }
1256    ::dog
1257    %
1258
1259\(Note that in this example, our __dog__ becomes a __snit::widget__,
1260because it has GUI behavior\. See [WIDGETS](#section17) for more\.\) Thus, if
1261we create a __dog__ called __\.spot__, it will create a Tk button called
1262__\.spot\.barkbtn__; when pressed, the button will call __$self bark__\.
1263
1264Now, this will work\-\-provided that __\.spot__ is never renamed to something
1265else\. But surely renaming widgets is abnormal? And so it is\-\-unless
1266__\.spot__ is the hull component of a __snit::widgetadaptor__\. If it is,
1267then it will be renamed, and __\.spot__ will become the name of the
1268__snit::widgetadaptor__ object\. When the button is pressed, the command
1269__$self bark__ will be handled by the __snit::widgetadaptor__, which
1270might or might not do the right thing\.
1271
1272There's a safer way to do it, and it looks like this:
1273
1274    % snit::widget dog {
1275        constructor {args} {
1276            #...
1277            button $win.barkbtn -text "Bark!" -command [mymethod bark]
1278            #...
1279        }
1280    }
1281    ::dog
1282    %
1283
1284The command __mymethod__ takes any number of arguments, and can be used like
1285__[list](\.\./\.\./\.\./\.\./index\.md\#list)__ to build up a callback command;
1286the only difference is that __mymethod__ returns a form of the command that
1287won't change even if the instance's name changes\.
1288
1289On the other hand, you might prefer to allow a widgetadaptor to override a
1290method such that your renamed widget will call the widgetadaptor's method
1291instead of its own\. In this case, using __\[list $self bark\]__ will do what
1292you want\.\.\.but this is a technique which should be used only in carefully
1293controlled circumstances\.
1294
1295## <a name='subsection40'></a>How do I delegate instance methods to a component?
1296
1297See [DELEGATION](#section16)\.
1298
1299# <a name='section6'></a>INSTANCE VARIABLES
1300
1301## <a name='subsection41'></a>What is an instance variable?
1302
1303An instance variable is a private variable associated with some particular Snit
1304object\. Instance variables can be scalars or arrays\.
1305
1306## <a name='subsection42'></a>How is a scalar instance variable defined?
1307
1308Scalar instance variables are defined in the type definition using the
1309__variable__ statement\. You can simply name it, or you can initialize it
1310with a value:
1311
1312    snit::type mytype {
1313        # Define variable "greeting" and initialize it with "Howdy!"
1314        variable greeting "Howdy!"
1315    }
1316
1317## <a name='subsection43'></a>How is an array instance variable defined?
1318
1319Array instance variables are also defined in the type definition using the
1320__variable__ command\. You can initialize them at the same time by specifying
1321the __\-array__ option:
1322
1323    snit::type mytype {
1324        # Define array variable "greetings"
1325        variable greetings -array {
1326            formal "Good Evening"
1327            casual "Howdy!"
1328        }
1329    }
1330
1331## <a name='subsection44'></a>What happens if I don't initialize an instance variable?
1332
1333Variables do not really exist until they are given values\. If you do not
1334initialize a variable when you define it, then you must be sure to assign a
1335value to it \(in the constructor, say, or in some method\) before you reference
1336it\.
1337
1338## <a name='subsection45'></a>Are there any limitations on instance variable names?
1339
1340Just a few\.
1341
1342First, every Snit object has a built\-in instance variable called
1343__options__, which should never be redefined\.
1344
1345Second, all names beginning with "Snit\_" are reserved for use by Snit internal
1346code\.
1347
1348Third, instance variable names containing the namespace delimiter \(__::__\)
1349are likely to cause great confusion\.
1350
1351## <a name='subsection46'></a>Do I need to declare my instance variables in my methods?
1352
1353No\. Once you've defined an instance variable in the type definition, it can be
1354used in any instance code \(instance methods, the constructor, and the
1355destructor\) without declaration\. This differs from normal Tcl practice, in which
1356all non\-local variables in a proc need to be declared\.
1357
1358There is a speed penalty to having all instance variables implicitly available
1359in all instance code\. Even though your code need not declare the variables
1360explicitly, Snit must still declare them, and that takes time\. If you have ten
1361instance variables, a method that uses none of them must still pay the
1362declaration penalty for all ten\. In most cases, the additional runtime cost is
1363negligible\. If extreme cases, you might wish to avoid it; there are two methods
1364for doing so\.
1365
1366The first is to define a single instance variable, an array, and store all of
1367your instance data in the array\. This way, you're only paying the declaration
1368penalty for one variable\-\-and you probably need the variable most of the time
1369anyway\. This method breaks down if your instance variables include multiple
1370arrays; in Tcl 8\.5, however, the __[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__
1371command might come to your rescue\.
1372
1373The second method is to declare your instance variables explicitly in your
1374instance code, while *not* including them in the type definition:
1375
1376    snit::type dog {
1377        constructor {} {
1378            variable mood
1379
1380            set mood happy
1381        }
1382
1383        method setmood {newMood} {
1384            variable mood
1385
1386            set mood $newMood
1387        }
1388
1389        method getmood {} {
1390            variable mood
1391
1392            return $mood
1393        }
1394    }
1395
1396This allows you to ensure that only the required variables are included in each
1397method, at the cost of longer code and run\-time errors when you forget to
1398declare a variable you need\.
1399
1400## <a name='subsection47'></a>How do I pass an instance variable's name to another object?
1401
1402In Tk, it's common to pass a widget a variable name; for example, Tk label
1403widgets have a __\-textvariable__ option which names the variable which will
1404contain the widget's text\. This allows the program to update the label's value
1405just by assigning a new value to the variable\.
1406
1407If you naively pass the instance variable name to the label widget, you'll be
1408confused by the result; Tk will assume that the name names a global variable\.
1409Instead, you need to provide a fully\-qualified variable name\. From within an
1410instance method or a constructor, you can fully qualify the variable's name
1411using the __myvar__ command:
1412
1413    snit::widget mywidget {
1414        variable labeltext ""
1415
1416        constructor {args} {
1417            # ...
1418
1419            label $win.label -textvariable [myvar labeltext]
1420
1421            # ...
1422        }
1423    }
1424
1425## <a name='subsection48'></a>How do I make an instance variable public?
1426
1427Practically speaking, you don't\. Instead, you'll implement public variables as
1428[OPTIONS](#section7)\. Alternatively, you can write [INSTANCE
1429METHODS](#section5) to set and get the variable's value\.
1430
1431# <a name='section7'></a>OPTIONS
1432
1433## <a name='subsection49'></a>What is an option?
1434
1435A type's options are the equivalent of what other object\-oriented languages
1436would call public member variables or properties: they are data values which can
1437be retrieved and \(usually\) set by the clients of an object\.
1438
1439Snit's implementation of options follows the Tk model fairly exactly, except
1440that __snit::type__ objects usually don't interact with [THE TK OPTION
1441DATABASE](#section19); __snit::widget__ and __snit::widgetadaptor__
1442objects, on the other hand, always do\.
1443
1444## <a name='subsection50'></a>How do I define an option?
1445
1446Options are defined in the type definition using the __option__ statement\.
1447Consider the following type, to be used in an application that manages a list of
1448dogs for a pet store:
1449
1450    snit::type dog {
1451        option -breed -default mongrel
1452        option -color -default brown
1453        option -akc   -default 0
1454        option -shots -default 0
1455    }
1456
1457According to this, a dog has four notable properties: a breed, a color, a flag
1458that says whether it's pedigreed with the American Kennel Club, and another flag
1459that says whether it has had its shots\. The default dog, evidently, is a brown
1460mutt\.
1461
1462There are a number of options you can specify when defining an option; if
1463__\-default__ is the only one, you can omit the word __\-default__ as
1464follows:
1465
1466    snit::type dog {
1467        option -breed mongrel
1468        option -color brown
1469        option -akc   0
1470        option -shots 0
1471    }
1472
1473If no __\-default__ value is specified, the option's default value will be
1474the empty string \(but see [THE TK OPTION DATABASE](#section19)\)\.
1475
1476The Snit man page refers to options like these as "locally defined" options\.
1477
1478## <a name='subsection51'></a>How can a client set options at object creation?
1479
1480The normal convention is that the client may pass any number of options and
1481their values after the object's name at object creation\. For example, the
1482__::dog__ command defined in the previous answer can now be used to create
1483individual dogs\. Any or all of the options may be set at creation time\.
1484
1485    % dog spot -breed beagle -color "mottled" -akc 1 -shots 1
1486    ::spot
1487    % dog fido -shots 1
1488    ::fido
1489    %
1490
1491So __::spot__ is a pedigreed beagle; __::fido__ is a typical mutt, but
1492his owners evidently take care of him, because he's had his shots\.
1493
1494*Note:* If the type defines a constructor, it can specify a different
1495object\-creation syntax\. See [CONSTRUCTORS](#section12) for more
1496information\.
1497
1498## <a name='subsection52'></a>How can a client retrieve an option's value?
1499
1500Retrieve option values using the __cget__ method:
1501
1502    % spot cget -color
1503    mottled
1504    % fido cget -breed
1505    mongrel
1506    %
1507
1508## <a name='subsection53'></a>How can a client set options after object creation?
1509
1510Any number of options may be set at one time using the __configure__
1511instance method\. Suppose that closer inspection shows that ::fido is not a brown
1512mongrel, but rather a rare Arctic Boar Hound of a lovely dun color:
1513
1514    % fido configure -color dun -breed "Arctic Boar Hound"
1515    % fido cget -color
1516    dun
1517    % fido cget -breed
1518    Arctic Boar Hound
1519
1520Alternatively, the __configurelist__ method takes a list of options and
1521values; occasionally this is more convenient:
1522
1523    % set features [list -color dun -breed "Arctic Boar Hound"]
1524    -color dun -breed {Arctic Boar Hound}
1525    % fido configurelist $features
1526    % fido cget -color
1527    dun
1528    % fido cget -breed
1529    Arctic Boar Hound
1530    %
1531
1532In Tcl 8\.5, the __\*__ keyword can be used with __configure__ in this
1533case:
1534
1535    % set features [list -color dun -breed "Arctic Boar Hound"]
1536    -color dun -breed {Arctic Boar Hound}
1537    % fido configure {*}$features
1538    % fido cget -color
1539    dun
1540    % fido cget -breed
1541    Arctic Boar Hound
1542    %
1543
1544The results are the same\.
1545
1546## <a name='subsection54'></a>How should an instance method access an option value?
1547
1548There are two ways an instance method can set and retrieve an option's value\.
1549One is to use the __configure__ and __cget__ methods, as shown below\.
1550
1551    % snit::type dog {
1552        option -weight 10
1553
1554        method gainWeight {} {
1555            set wt [$self cget -weight]
1556            incr wt
1557            $self configure -weight $wt
1558        }
1559    }
1560    ::dog
1561    % dog fido
1562    ::fido
1563    % fido cget -weight
1564    10
1565    % fido gainWeight
1566    % fido cget -weight
1567    11
1568    %
1569
1570Alternatively, Snit provides a built\-in array instance variable called
1571__options__\. The indices are the option names; the values are the option
1572values\. The method __gainWeight__ can thus be rewritten as follows:
1573
1574    method gainWeight {} {
1575        incr options(-weight)
1576    }
1577
1578As you can see, using the __options__ variable involves considerably less
1579typing and is the usual way to do it\. But if you use __\-configuremethod__ or
1580__\-cgetmethod__ \(described in the following answers\), you might wish to use
1581the __configure__ and __cget__ methods anyway, just so that any special
1582processing you've implemented is sure to get done\. Also, if the option is
1583delegated to a component then __configure__ and __cget__ are the only
1584way to access it without accessing the component directly\. See
1585[DELEGATION](#section16) for more information\.
1586
1587## <a name='subsection55'></a>How can I make an option read\-only?
1588
1589Define the option with __\-readonly yes__\.
1590
1591Suppose you've got an option that determines how instances of your type are
1592constructed; it must be set at creation time, after which it's constant\. For
1593example, a dog never changes its breed; it might or might not have had its
1594shots, and if not can have them at a later time\. __\-breed__ should be
1595read\-only, but __\-shots__ should not be\.
1596
1597    % snit::type dog {
1598        option -breed -default mongrel -readonly yes
1599        option -shots -default no
1600    }
1601    ::dog
1602    % dog fido -breed retriever
1603    ::fido
1604    % fido configure -shots yes
1605    % fido configure -breed terrier
1606    option -breed can only be set at instance creation
1607    %
1608
1609## <a name='subsection56'></a>How can I catch accesses to an option's value?
1610
1611Define a __\-cgetmethod__ for the option\.
1612
1613## <a name='subsection57'></a>What is a \-cgetmethod?
1614
1615A __\-cgetmethod__ is a method that's called whenever the related option's
1616value is queried via the __cget__ instance method\. The handler can compute
1617the option's value, retrieve it from a database, or do anything else you'd like
1618it to do\.
1619
1620Here's what the default behavior would look like if written using a
1621__\-cgetmethod__:
1622
1623    snit::type dog {
1624        option -color -default brown -cgetmethod GetOption
1625
1626        method GetOption {option} {
1627            return $options($option)
1628        }
1629    }
1630
1631Any instance method can be used, provided that it takes one argument, the name
1632of the option whose value is to be retrieved\.
1633
1634## <a name='subsection58'></a>How can I catch changes to an option's value?
1635
1636Define a __\-configuremethod__ for the option\.
1637
1638## <a name='subsection59'></a>What is a \-configuremethod?
1639
1640A __\-configuremethod__ is a method that's called whenever the related option
1641is given a new value via the __configure__ or __configurelist__ instance
1642methods\. The method can pass the value on to some other object, store it in a
1643database, or do anything else you'd like it to do\.
1644
1645Here's what the default configuration behavior would look like if written using
1646a __\-configuremethod__:
1647
1648    snit::type dog {
1649        option -color -default brown -configuremethod SetOption
1650
1651        method SetOption {option value} {
1652            set options($option) $value
1653        }
1654    }
1655
1656Any instance method can be used, provided that it takes two arguments, the name
1657of the option and the new value\.
1658
1659Note that if your method doesn't store the value in the __options__ array,
1660the __options__ array won't get updated\.
1661
1662## <a name='subsection60'></a>How can I validate an option's value?
1663
1664Define a __\-validatemethod__\.
1665
1666## <a name='subsection61'></a>What is a \-validatemethod?
1667
1668A __\-validatemethod__ is a method that's called whenever the related option
1669is given a new value via the __configure__ or __configurelist__ instance
1670methods\. It's the method's responsibility to determine whether the new value is
1671valid, and throw an error if it isn't\. The __\-validatemethod__, if any, is
1672called before the value is stored in the __options__ array; in particular,
1673it's called before the __\-configuremethod__, if any\.
1674
1675For example, suppose an option always takes a Boolean value\. You can ensure that
1676the value is in fact a valid Boolean like this:
1677
1678    % snit::type dog {
1679        option -shots -default no -validatemethod BooleanOption
1680
1681        method BooleanOption {option value} {
1682            if {![string is boolean -strict $value]} {
1683                error "expected a boolean value, got \"$value\""
1684            }
1685        }
1686    }
1687    ::dog
1688    % dog fido
1689    % fido configure -shots yes
1690    % fido configure -shots NotABooleanValue
1691    expected a boolean value, got "NotABooleanValue"
1692    %
1693
1694Note that the same __\-validatemethod__ can be used to validate any number of
1695boolean options\.
1696
1697Any method can be a __\-validatemethod__ provided that it takes two
1698arguments, the option name and the new option value\.
1699
1700# <a name='section8'></a>TYPE VARIABLES
1701
1702## <a name='subsection62'></a>What is a type variable?
1703
1704A type variable is a private variable associated with a Snit type rather than
1705with a particular instance of the type\. In C\+\+ and Java, the term *static
1706member variable* is used for the same notion\. Type variables can be scalars or
1707arrays\.
1708
1709## <a name='subsection63'></a>How is a scalar type variable defined?
1710
1711Scalar type variables are defined in the type definition using the
1712__typevariable__ statement\. You can simply name it, or you can initialize it
1713with a value:
1714
1715    snit::type mytype {
1716        # Define variable "greeting" and initialize it with "Howdy!"
1717        typevariable greeting "Howdy!"
1718    }
1719
1720Every object of type __mytype__ now has access to a single variable called
1721__greeting__\.
1722
1723## <a name='subsection64'></a>How is an array\-valued type variable defined?
1724
1725Array\-valued type variables are also defined using the __typevariable__
1726command; to initialize them, include the __\-array__ option:
1727
1728    snit::type mytype {
1729        # Define typearray variable "greetings"
1730        typevariable greetings -array {
1731            formal "Good Evening"
1732            casual "Howdy!"
1733        }
1734    }
1735
1736## <a name='subsection65'></a>What happens if I don't initialize a type variable?
1737
1738Variables do not really exist until they are given values\. If you do not
1739initialize a variable when you define it, then you must be sure to assign a
1740value to it \(in the type constructor, say\) before you reference it\.
1741
1742## <a name='subsection66'></a>Are there any limitations on type variable names?
1743
1744Type variable names have the same restrictions as the names of [INSTANCE
1745VARIABLES](#section6) do\.
1746
1747## <a name='subsection67'></a>Do I need to declare my type variables in my methods?
1748
1749No\. Once you've defined a type variable in the type definition, it can be used
1750in [INSTANCE METHODS](#section5) or [TYPE METHODS](#section9) without
1751declaration\. This differs from normal Tcl practice, in which all non\-local
1752variables in a proc need to be declared\.
1753
1754Type variables are subject to the same speed/readability tradeoffs as instance
1755variables; see [Do I need to declare my instance variables in my
1756methods?](#subsection46)
1757
1758## <a name='subsection68'></a>How do I pass a type variable's name to another object?
1759
1760In Tk, it's common to pass a widget a variable name; for example, Tk label
1761widgets have a __\-textvariable__ option which names the variable which will
1762contain the widget's text\. This allows the program to update the label's value
1763just by assigning a new value to the variable\.
1764
1765If you naively pass a type variable name to the label widget, you'll be confused
1766by the result; Tk will assume that the name names a global variable\. Instead,
1767you need to provide a fully\-qualified variable name\. From within an instance
1768method or a constructor, you can fully qualify the type variable's name using
1769the __mytypevar__ command:
1770
1771    snit::widget mywidget {
1772        typevariable labeltext ""
1773
1774        constructor {args} {
1775            # ...
1776
1777            label $win.label -textvariable [mytypevar labeltext]
1778
1779            # ...
1780        }
1781    }
1782
1783## <a name='subsection69'></a>How do I make a type variable public?
1784
1785There are two ways to do this\. The preferred way is to write a pair of [TYPE
1786METHODS](#section9) to set and query the type variable's value\.
1787
1788Type variables are stored in the type's namespace, which has the same name as
1789the type itself\. Thus, you can also publicize the type variable's name in your
1790documentation so that clients can access it directly\. For example,
1791
1792    snit::type mytype {
1793        typevariable myvariable
1794    }
1795
1796    set ::mytype::myvariable "New Value"
1797
1798# <a name='section9'></a>TYPE METHODS
1799
1800## <a name='subsection70'></a>What is a type method?
1801
1802A type method is a procedure associated with the type itself rather than with
1803any specific instance of the type, and called as a subcommand of the type
1804command\.
1805
1806## <a name='subsection71'></a>How do I define a type method?
1807
1808Type methods are defined in the type definition using the __typemethod__
1809statement:
1810
1811    snit::type dog {
1812        # List of pedigreed dogs
1813        typevariable pedigreed
1814
1815        typemethod pedigreedDogs {} {
1816            return $pedigreed
1817        }
1818    }
1819
1820Suppose the __dog__ type maintains a list of the names of the dogs that have
1821pedigrees\. The __pedigreedDogs__ type method returns this list\.
1822
1823The __typemethod__ statement looks just like a normal Tcl
1824__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, except that it appears in a
1825__snit::type__ definition\. Notice that every type method gets an implicit
1826argument called __type__, which contains the fully\-qualified type name\.
1827
1828## <a name='subsection72'></a>How does a client call a type method?
1829
1830The type method name becomes a subcommand of the type's command\. For example,
1831assuming that the constructor adds each pedigreed dog to the list of
1832__pedigreedDogs__,
1833
1834    snit::type dog {
1835        option -pedigreed 0
1836
1837        # List of pedigreed dogs
1838        typevariable pedigreed
1839
1840        typemethod pedigreedDogs {} {
1841            return $pedigreed
1842        }
1843
1844        # ...
1845    }
1846
1847    dog spot -pedigreed 1
1848    dog fido
1849
1850    foreach dog [dog pedigreedDogs] { ... }
1851
1852## <a name='subsection73'></a>Are there any limitations on type method names?
1853
1854Not really, so long as you avoid the standard type method names: __create__,
1855__destroy__, and __info__\.
1856
1857## <a name='subsection74'></a>How do I make a type method private?
1858
1859It's sometimes useful to define private type methods, that is, type methods
1860intended to be called only by other type or instance methods of the same object\.
1861
1862Snit doesn't implement any access control on type methods; by convention, the
1863names of public methods begin with a lower\-case letter, and the names of private
1864methods begin with an upper\-case letter\.
1865
1866Alternatively, a Snit __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ can be used
1867as a private type method; see [PROCS](#section10)\.
1868
1869## <a name='subsection75'></a>Are there any limitations on type method arguments?
1870
1871Method argument lists are defined just like normal Tcl proc argument lists; in
1872particular, they can include arguments with default values and the __args__
1873argument\.
1874
1875However, every type method is called with an implicit argument called
1876__type__ that contains the name of the type command\. In addition, type
1877methods should by convention avoid using the names of the arguments implicitly
1878defined for [INSTANCE METHODS](#section5)\.
1879
1880## <a name='subsection76'></a>How does an instance or type method call a type method?
1881
1882If an instance or type method needs to call a type method, it should use
1883__$type__ to do so:
1884
1885    snit::type dog {
1886
1887        typemethod pedigreedDogs {} { ... }
1888
1889        typemethod printPedigrees {} {
1890            foreach obj [$type pedigreedDogs] { ... }
1891        }
1892    }
1893
1894## <a name='subsection77'></a>How do I pass a type method as a callback?
1895
1896It's common in Tcl to pass a snippet of code to another object, for it to call
1897later\. Because types cannot be renamed, you can just use the type name, or, if
1898the callback is registered from within a type method, __type__\. For example,
1899suppose we want to print a list of pedigreed dogs when a Tk button is pushed:
1900
1901    button .btn -text "Pedigrees" -command [list dog printPedigrees]
1902    pack .btn
1903
1904Alternatively, from a method or type method you can use the __mytypemethod__
1905command, just as you would use __mymethod__ to define a callback command for
1906[INSTANCE METHODS](#section5)\.
1907
1908## <a name='subsection78'></a>Can type methods be hierarchical?
1909
1910Yes, you can define hierarchical type methods in just the same way as you can
1911define hierarchical instance methods\. See [INSTANCE METHODS](#section5) for
1912more\.
1913
1914# <a name='section10'></a>PROCS
1915
1916## <a name='subsection79'></a>What is a proc?
1917
1918A Snit __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ is really just a Tcl proc
1919defined within the type's namespace\. You can use procs for private code that
1920isn't related to any particular instance\.
1921
1922## <a name='subsection80'></a>How do I define a proc?
1923
1924Procs are defined by including a __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__
1925statement in the type definition:
1926
1927    snit::type mytype {
1928        # Pops and returns the first item from the list stored in the
1929        # listvar, updating the listvar
1930       proc pop {listvar} { ... }
1931
1932       # ...
1933    }
1934
1935## <a name='subsection81'></a>Are there any limitations on proc names?
1936
1937Any name can be used, so long as it does not begin with __Snit\___; names
1938beginning with __Snit\___ are reserved for Snit's own use\. However, the wise
1939programmer will avoid __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ names
1940\(__[set](\.\./\.\./\.\./\.\./index\.md\#set)__,
1941__[list](\.\./\.\./\.\./\.\./index\.md\#list)__, __if__, etc\.\) that would
1942shadow standard Tcl command names\.
1943
1944__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ names, being private, should begin
1945with a capital letter according to convention; however, as there are typically
1946no public __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__s in the type's namespace
1947it doesn't matter much either way\.
1948
1949## <a name='subsection82'></a>How does a method call a proc?
1950
1951Just like it calls any Tcl command\. For example,
1952
1953    snit::type mytype {
1954        # Pops and returns the first item from the list stored in the
1955        # listvar, updating the listvar
1956        proc pop {listvar} { ... }
1957
1958        variable requestQueue {}
1959
1960        # Get one request from the queue and process it.
1961        method processRequest {} {
1962            set req [pop requestQueue]
1963        }
1964    }
1965
1966## <a name='subsection83'></a>How can I pass a proc to another object as a callback?
1967
1968The __myproc__ command returns a callback command for the
1969__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, just as __mymethod__ does for
1970a method\.
1971
1972# <a name='section11'></a>TYPE CONSTRUCTORS
1973
1974## <a name='subsection84'></a>What is a type constructor?
1975
1976A type constructor is a body of code that initializes the type as a whole,
1977rather like a C\+\+ static initializer\. The body of a type constructor is executed
1978once when the type is defined, and never again\.
1979
1980A type can have at most one type constructor\.
1981
1982## <a name='subsection85'></a>How do I define a type constructor?
1983
1984A type constructor is defined by using the __typeconstructor__ statement in
1985the type definition\. For example, suppose the type uses an array\-valued type
1986variable as a look\-up table, and the values in the array have to be computed at
1987start\-up\.
1988
1989    % snit::type mytype {
1990        typevariable lookupTable
1991
1992        typeconstructor {
1993            array set lookupTable {key value...}
1994        }
1995    }
1996
1997# <a name='section12'></a>CONSTRUCTORS
1998
1999## <a name='subsection86'></a>What is a constructor?
2000
2001In object\-oriented programming, an object's constructor is responsible for
2002initializing the object completely at creation time\. The constructor receives
2003the list of options passed to the __snit::type__ command's __create__
2004method and can then do whatever it likes\. That might include computing instance
2005variable values, reading data from files, creating other objects, updating type
2006and instance variables, and so forth\.
2007
2008The constructor's return value is ignored \(unless it's an error, of course\)\.
2009
2010## <a name='subsection87'></a>How do I define a constructor?
2011
2012A constructor is defined by using the __constructor__ statement in the type
2013definition\. Suppose that it's desired to keep a list of all pedigreed dogs\. The
2014list can be maintained in a type variable and retrieved by a type method\.
2015Whenever a dog is created, it can add itself to the list\-\-provided that it's
2016registered with the American Kennel Club\.
2017
2018    % snit::type dog {
2019        option -akc 0
2020
2021        typevariable akcList {}
2022
2023        constructor {args} {
2024            $self configurelist $args
2025
2026            if {$options(-akc)} {
2027                lappend akcList $self
2028            }
2029        }
2030
2031        typemethod akclist {} {
2032            return $akcList
2033        }
2034    }
2035    ::dog
2036    % dog spot -akc 1
2037    ::spot
2038    % dog fido
2039    ::fido
2040    % dog akclist
2041    ::spot
2042    %
2043
2044## <a name='subsection88'></a>What does the default constructor do?
2045
2046If you don't provide a constructor explicitly, you get the default constructor,
2047which is identical to the explicitly\-defined constructor shown here:
2048
2049    snit::type dog {
2050        constructor {args} {
2051            $self configurelist $args
2052        }
2053    }
2054
2055When the constructor is called, __args__ will be set to the list of
2056arguments that follow the object's name\. The constructor is allowed to interpret
2057this list any way it chooses; the normal convention is to assume that it's a
2058list of option names and values, as shown in the example above\. If you simply
2059want to save the option values, you should use the __configurelist__ method,
2060as shown\.
2061
2062## <a name='subsection89'></a>Can I choose a different set of arguments for the constructor?
2063
2064Yes, you can\. For example, suppose we wanted to be sure that the breed was
2065explicitly stated for every dog at creation time, and couldn't be changed
2066thereafter\. One way to do that is as follows:
2067
2068    % snit::type dog {
2069        variable breed
2070
2071        option -color brown
2072        option -akc 0
2073
2074        constructor {theBreed args} {
2075            set breed $theBreed
2076            $self configurelist $args
2077        }
2078
2079        method breed {} { return $breed }
2080    }
2081    ::dog
2082    % dog spot dalmatian -color spotted -akc 1
2083    ::spot
2084    % spot breed
2085    dalmatian
2086
2087The drawback is that this syntax is non\-standard, and may limit the
2088compatibility of your new type with other people's code\. For example, Snit
2089assumes that it can create [COMPONENTS](#section14) using the standard
2090creation syntax\.
2091
2092## <a name='subsection90'></a>Are there any limitations on constructor arguments?
2093
2094Constructor argument lists are subject to the same limitations as those on
2095instance method argument lists\. It has the same implicit arguments, and can
2096contain default values and the __args__ argument\.
2097
2098## <a name='subsection91'></a>Is there anything special about writing the constructor?
2099
2100Yes\. Writing the constructor can be tricky if you're delegating options to
2101components, and there are specific issues relating to __snit::widget__s and
2102__snit::widgetadaptor__s\. See [DELEGATION](#section16),
2103[WIDGETS](#section17), [WIDGET ADAPTORS](#section18), and [THE TK
2104OPTION DATABASE](#section19)\.
2105
2106# <a name='section13'></a>DESTRUCTORS
2107
2108## <a name='subsection92'></a>What is a destructor?
2109
2110A destructor is a special kind of method that's called when an object is
2111destroyed\. It's responsible for doing any necessary clean\-up when the object
2112goes away: destroying [COMPONENTS](#section14), closing files, and so
2113forth\.
2114
2115## <a name='subsection93'></a>How do I define a destructor?
2116
2117Destructors are defined by using the __destructor__ statement in the type
2118definition\.
2119
2120Suppose we're maintaining a list of pedigreed dogs; then we'll want to remove
2121dogs from it when they are destroyed\.
2122
2123    snit::type dog {
2124        option -akc 0
2125
2126        typevariable akcList {}
2127
2128        constructor {args} {
2129            $self configurelist $args
2130
2131            if {$options(-akc)} {
2132                lappend akcList $self
2133            }
2134        }
2135
2136        destructor {
2137            set ndx [lsearch $akcList $self]
2138
2139            if {$ndx != -1} {
2140                set akcList [lreplace $akcList $ndx $ndx]
2141            }
2142        }
2143
2144        typemethod akclist {} {
2145            return $akcList
2146        }
2147    }
2148
2149## <a name='subsection94'></a>Are there any limitations on destructor arguments?
2150
2151Yes; a destructor has no explicit arguments\.
2152
2153## <a name='subsection95'></a>What implicit arguments are passed to the destructor?
2154
2155The destructor gets the same implicit arguments that are passed to [INSTANCE
2156METHODS](#section5): __type__, __selfns__, __win__, and
2157__self__\.
2158
2159## <a name='subsection96'></a>Must components be destroyed explicitly?
2160
2161Yes and no\.
2162
2163Any Tk widgets created by a __snit::widget__ or __snit::widgetadaptor__
2164will be destroyed automatically by Tk when the megawidget is destroyed, in
2165keeping with normal Tk behavior \(destroying a parent widget destroys the whole
2166tree\)\.
2167
2168Components of normal __snit::types__, on the other hand, are never destroyed
2169automatically, nor are non\-widget components of Snit megawidgets\. If your object
2170creates them in its constructor, then it should generally destroy them in its
2171destructor\.
2172
2173## <a name='subsection97'></a>Is there any special about writing a destructor?
2174
2175Yes\. If an object's constructor throws an error, the object's destructor will be
2176called to clean up; this means that the object might not be completely
2177constructed when the destructor is called\. This can cause the destructor to
2178throw its own error; the result is usually misleading, confusing, and unhelpful\.
2179Consequently, it's important to write your destructor so that it's fail\-safe\.
2180
2181For example, a __dog__ might create a __tail__ component; the component
2182will need to be destroyed\. But suppose there's an error while processing the
2183creation options\-\-the destructor will be called, and there will be no
2184__tail__ to destroy\. The simplest solution is generally to catch and ignore
2185any errors while destroying components\.
2186
2187    snit::type dog {
2188        component tail
2189
2190        constructor {args} {
2191            $self configurelist $args
2192
2193            set tail [tail %AUTO%]
2194        }
2195
2196        destructor {
2197            catch {$tail destroy}
2198        }
2199    }
2200
2201# <a name='section14'></a>COMPONENTS
2202
2203## <a name='subsection98'></a>What is a component?
2204
2205Often an object will create and manage a number of other objects\. A Snit
2206megawidget, for example, will often create a number of Tk widgets\. These objects
2207are part of the main object; it is composed of them, so they are called
2208components of the object\.
2209
2210But Snit also has a more precise meaning for [COMPONENT](#section14)\. The
2211components of a Snit object are those objects to which methods or options can be
2212delegated\. \(See [DELEGATION](#section16) for more information about
2213delegation\.\)
2214
2215## <a name='subsection99'></a>How do I declare a component?
2216
2217First, you must decide what role a component plays within your object, and give
2218the role a name\. Then, you declare the component using its role name and the
2219__component__ statement\. The __component__ statement declares an
2220*instance variable* which is used to store the component's command name when
2221the component is created\.
2222
2223For example, suppose your __dog__ object creates a __tail__ object \(the
2224better to wag with, no doubt\):
2225
2226    snit::type dog {
2227        component mytail
2228
2229        constructor {args} {
2230            # Create and save the component's command
2231            set mytail [tail %AUTO% -partof $self]
2232            $self configurelist $args
2233        }
2234
2235        method wag {} {
2236            $mytail wag
2237        }
2238    }
2239
2240As shown here, it doesn't matter what the __tail__ object's real name is;
2241the __dog__ object refers to it by its component name\.
2242
2243The above example shows one way to delegate the __wag__ method to the
2244__mytail__ component; see [DELEGATION](#section16) for an easier way\.
2245
2246## <a name='subsection100'></a>How is a component named?
2247
2248A component has two names\. The first name is that of the component variable;
2249this represents the role the component object plays within the Snit object\. This
2250is the component name proper, and is the name used to refer to the component
2251within Snit code\. The second name is the name of the actual component object
2252created by the Snit object's constructor\. This second name is always a Tcl
2253command name, and is referred to as the component's object name\.
2254
2255In the example in the previous question, the component name is __mytail__;
2256the __mytail__ component's object name is chosen automatically by Snit since
2257__%AUTO%__ was used when the component object was created\.
2258
2259## <a name='subsection101'></a>Are there any limitations on component names?
2260
2261Yes\. __snit::widget__ and __snit::widgetadaptor__ objects have a special
2262component called the __hull__ component; thus, the name __hull__ should
2263be used for no other purpose\.
2264
2265Otherwise, since component names are in fact instance variable names they must
2266follow the rules for [INSTANCE VARIABLES](#section6)\.
2267
2268## <a name='subsection102'></a>What is an owned component?
2269
2270An *owned* component is a component whose object command's lifetime is
2271controlled by the __snit::type__ or __snit::widget__\.
2272
2273As stated above, a component is an object to which our object can delegate
2274methods or options\. Under this definition, our object will usually create its
2275component objects, but not necessarily\. Consider the following: a dog object has
2276a tail component; but tail knows that it's part of the dog:
2277
2278    snit::type dog {
2279        component mytail
2280
2281        constructor {args} {
2282            set mytail [tail %AUTO% -partof $self]
2283            $self configurelist $args
2284        }
2285
2286        destructor {
2287            catch {$mytail destroy}
2288        }
2289
2290        delegate method wagtail to mytail as wag
2291
2292        method bark {} {
2293            return "$self barked."
2294        }
2295    }
2296
2297     snit::type tail {
2298         component mydog
2299         option -partof -readonly yes
2300
2301         constructor {args} {
2302             $self configurelist $args
2303             set mydog $options(-partof)
2304         }
2305
2306         method wag {} {
2307             return "Wag, wag."
2308         }
2309
2310         method pull {} {
2311             $mydog bark
2312         }
2313     }
2314
2315Thus, if you ask a dog to wag its tail, it tells its tail to wag; and if you
2316pull the dog's tail, the tail tells the dog to bark\. In this scenario, the tail
2317is a component of the dog, and the dog is a component of the tail, but the dog
2318owns the tail and not the other way around\.
2319
2320## <a name='subsection103'></a>What does the install command do?
2321
2322The __install__ command creates an owned component using a specified
2323command, and assigns the result to the component's instance variable\. For
2324example:
2325
2326    snit::type dog {
2327        component mytail
2328
2329        constructor {args} {
2330            # set mytail [tail %AUTO% -partof $self]
2331            install mytail using tail %AUTO% -partof $self
2332            $self configurelist $args
2333        }
2334    }
2335
2336In a __snit::type__'s code, the __install__ command shown above is
2337equivalent to the __set mytail__ command that's commented out\. In a
2338__snit::widget__'s or __snit::widgetadaptor__'s, code, however, the
2339__install__ command also queries [THE TK OPTION DATABASE](#section19)
2340and initializes the new component's options accordingly\. For consistency, it's a
2341good idea to get in the habit of using __install__ for all owned components\.
2342
2343## <a name='subsection104'></a>Must owned components be created in the constructor?
2344
2345No, not necessarily\. In fact, there's no reason why an object can't destroy and
2346recreate a component multiple times over its own lifetime\.
2347
2348## <a name='subsection105'></a>Are there any limitations on component object names?
2349
2350Yes\.
2351
2352Component objects which are Tk widgets or megawidgets must have valid Tk window
2353names\.
2354
2355Component objects which are not widgets or megawidgets must have fully\-qualified
2356command names, i\.e\., names which include the full namespace of the command\. Note
2357that Snit always creates objects with fully qualified names\.
2358
2359Next, the object names of components and owned by your object must be unique\.
2360This is no problem for widget components, since widget names are always unique;
2361but consider the following code:
2362
2363    snit::type tail { ... }
2364
2365    snit::type dog {
2366        delegate method wag to mytail
2367
2368        constructor {} {
2369            install mytail using tail mytail
2370        }
2371    }
2372
2373This code uses the component name, __mytail__, as the component object name\.
2374This is not good, and here's why: Snit instance code executes in the Snit type's
2375namespace\. In this case, the __mytail__ component is created in the
2376__::dog::__ namespace, and will thus have the name __::dog::mytail__\.
2377
2378Now, suppose you create two dogs\. Both dogs will attempt to create a tail called
2379__::dog::mytail__\. The first will succeed, and the second will fail, since
2380Snit won't let you create an object if its name is already a command\. Here are
2381two ways to avoid this situation:
2382
2383First, if the component type is a __snit::type__ you can specify
2384__%AUTO%__ as its name, and be guaranteed to get a unique name\. This is the
2385safest thing to do:
2386
2387    install mytail using tail %AUTO%
2388
2389If the component type isn't a __snit::type__ you can create the component in
2390the object's instance namespace:
2391
2392    install mytail using tail ${selfns}::mytail
2393
2394Make sure you pick a unique name within the instance namespace\.
2395
2396## <a name='subsection106'></a>Must I destroy the components I own?
2397
2398That depends\. When a parent widget is destroyed, all child widgets are destroyed
2399automatically\. Thus, if your object is a __snit::widget__ or
2400__snit::widgetadaptor__ you don't need to destroy any components that are
2401widgets, because they will generally be children or descendants of your
2402megawidget\.
2403
2404If your object is an instance of __snit::type__, though, none of its owned
2405components will be destroyed automatically, nor will be non\-widget components of
2406a __snit::widget__ be destroyed automatically\. All such owned components
2407must be destroyed explicitly, or they won't be destroyed at all\.
2408
2409## <a name='subsection107'></a>Can I expose a component's object command as part of my interface?
2410
2411Yes, and there are two ways to do it\. The most appropriate way is usually to use
2412[DELEGATION](#section16)\. Delegation allows you to pass the options and
2413methods you specify along to particular components\. This effectively hides the
2414components from the users of your type, and ensures good encapsulation\.
2415
2416However, there are times when it's appropriate, not to mention simpler, just to
2417make the entire component part of your type's public interface\.
2418
2419## <a name='subsection108'></a>How do I expose a component's object command?
2420
2421When you declare the component, specify the __component__ statement's
2422__\-public__ option\. The value of this option is the name of a method which
2423will be delegated to your component's object command\.
2424
2425For example, supposed you've written a combobox megawidget which owns a listbox
2426widget, and you want to make the listbox's entire interface public\. You can do
2427it like this:
2428
2429    snit::widget combobox {
2430         component listbox -public listbox
2431
2432         constructor {args} {
2433             install listbox using listbox $win.listbox ....
2434         }
2435    }
2436
2437    combobox .mycombo
2438    .mycombo listbox configure -width 30
2439
2440Your comobox widget, __\.mycombo__, now has a __listbox__ method which
2441has all of the same subcommands as the listbox widget itself\. Thus, the above
2442code sets the listbox component's width to 30\.
2443
2444Usually you'll let the method name be the same as the component name; however,
2445you can name it anything you like\.
2446
2447# <a name='section15'></a>TYPE COMPONENTS
2448
2449## <a name='subsection109'></a>What is a type component?
2450
2451A type component is a component that belongs to the type itself instead of to a
2452particular instance of the type\. The relationship between components and type
2453components is the same as the relationship between [INSTANCE
2454VARIABLES](#section6) and [TYPE VARIABLES](#section8)\. Both [INSTANCE
2455METHODS](#section5) and [TYPE METHODS](#section9) can be delegated to
2456type components\.
2457
2458Once you understand [COMPONENTS](#section14) and
2459[DELEGATION](#section16), type components are just more of the same\.
2460
2461## <a name='subsection110'></a>How do I declare a type component?
2462
2463Declare a type component using the __typecomponent__ statement\. It takes the
2464same options \(__\-inherit__ and __\-public__\) as the __component__
2465statement does, and defines a type variable to hold the type component's object
2466command\.
2467
2468Suppose in your model you've got many dogs, but only one veterinarian\. You might
2469make the veterinarian a type component\.
2470
2471    snit::type veterinarian { ... }
2472
2473    snit::type dog {
2474        typecomponent vet
2475
2476        # ...
2477    }
2478
2479## <a name='subsection111'></a>How do I install a type component?
2480
2481Just use the __[set](\.\./\.\./\.\./\.\./index\.md\#set)__ command to assign the
2482component's object command to the type component\. Because types \(even
2483__snit::widget__ types\) are not widgets, and do not have options anyway, the
2484extra features of the __install__ command are not needed\.
2485
2486You'll usually install type components in the type constructor, as shown here:
2487
2488    snit::type veterinarian { ... }
2489
2490    snit::type dog {
2491        typecomponent vet
2492
2493        typeconstructor {
2494            set vet [veterinarian %AUTO%]
2495        }
2496    }
2497
2498## <a name='subsection112'></a>Are there any limitations on type component names?
2499
2500Yes, the same as on [INSTANCE VARIABLES](#section6), [TYPE
2501VARIABLES](#section8), and normal [COMPONENTS](#section14)\.
2502
2503# <a name='section16'></a>DELEGATION
2504
2505## <a name='subsection113'></a>What is delegation?
2506
2507Delegation, simply put, is when you pass a task you've been given to one of your
2508assistants\. \(You do have assistants, don't you?\) Snit objects can do the same
2509thing\. The following example shows one way in which the __dog__ object can
2510delegate its __wag__ method and its __\-taillength__ option to its
2511__tail__ component\.
2512
2513    snit::type dog {
2514        variable mytail
2515
2516        option -taillength -configuremethod SetTailOption -cgetmethod GetTailOption
2517
2518        method SetTailOption {option value} {
2519             $mytail configure $option $value
2520        }
2521
2522        method GetTailOption {option} {
2523             $mytail cget $option
2524        }
2525
2526        method wag {} {
2527            $mytail wag
2528        }
2529
2530        constructor {args} {
2531            install mytail using tail %AUTO% -partof $self
2532            $self configurelist $args
2533        }
2534
2535    }
2536
2537This is the hard way to do it, by it demonstrates what delegation is all about\.
2538See the following answers for the easy way to do it\.
2539
2540Note that the constructor calls the __configurelist__ method
2541__[after](\.\./\.\./\.\./\.\./index\.md\#after)__ it creates its __tail__;
2542otherwise, if __\-taillength__ appeared in the list of __args__ we'd get
2543an error\.
2544
2545## <a name='subsection114'></a>How can I delegate a method to a component object?
2546
2547Delegation occurs frequently enough that Snit makes it easy\. Any method can be
2548delegated to any component or type component by placing a single
2549__delegate__ statement in the type definition\. \(See
2550[COMPONENTS](#section14) and [TYPE COMPONENTS](#section15) for more
2551information about component names\.\)
2552
2553For example, here's a much better way to delegate the __dog__ object's
2554__wag__ method:
2555
2556    % snit::type dog {
2557        delegate method wag to mytail
2558
2559        constructor {} {
2560            install mytail using tail %AUTO%
2561        }
2562    }
2563    ::dog
2564    % snit::type tail {
2565        method wag {} { return "Wag, wag, wag."}
2566    }
2567    ::tail
2568    % dog spot
2569    ::spot
2570    % spot wag
2571    Wag, wag, wag.
2572
2573This code has the same effect as the code shown under the previous question:
2574when a __dog__'s __wag__ method is called, the call and its arguments
2575are passed along automatically to the __tail__ object\.
2576
2577Note that when a component is mentioned in a __delegate__ statement, the
2578component's instance variable is defined implicitly\. However, it's still good
2579practice to declare it explicitly using the __component__ statement\.
2580
2581Note also that you can define a method name using the
2582__[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement, or you can define
2583it using __delegate__; you can't do both\.
2584
2585## <a name='subsection115'></a>Can I delegate to a method with a different name?
2586
2587Suppose you wanted to delegate the __dog__'s __wagtail__ method to the
2588__tail__'s __wag__ method\. After all you wag the tail, not the dog\. It's
2589easily done:
2590
2591    snit::type dog {
2592        delegate method wagtail to mytail as wag
2593
2594        constructor {args} {
2595            install mytail using tail %AUTO% -partof $self
2596            $self configurelist $args
2597        }
2598    }
2599
2600## <a name='subsection116'></a>Can I delegate to a method with additional arguments?
2601
2602Suppose the __tail__'s __wag__ method takes as an argument the number of
2603times the tail should be wagged\. You want to delegate the __dog__'s
2604__wagtail__ method to the __tail__'s __wag__ method, specifying that
2605the tail should be wagged exactly three times\. This is easily done, too:
2606
2607    snit::type dog {
2608        delegate method wagtail to mytail as {wag 3}
2609        # ...
2610    }
2611
2612    snit::type tail {
2613        method wag {count} {
2614            return [string repeat "Wag " $count]
2615        }
2616        # ...
2617    }
2618
2619## <a name='subsection117'></a>Can I delegate a method to something other than an object?
2620
2621Normal method delegation assumes that you're delegating a method \(a subcommand
2622of an object command\) to a method of another object \(a subcommand of a different
2623object command\)\. But not all Tcl objects follow Tk conventions, and not
2624everything you'd to which you'd like to delegate a method is necessary an
2625object\. Consequently, Snit makes it easy to delegate a method to pretty much
2626anything you like using the __delegate__ statement's __using__ clause\.
2627
2628Suppose your dog simulation stores dogs in a database, each dog as a single
2629record\. The database API you're using provides a number of commands to manage
2630records; each takes the record ID \(a string you choose\) as its first argument\.
2631For example, __saverec__ saves a record\. If you let the record ID be the
2632name of the dog object, you can delegate the dog's __save__ method to the
2633__saverec__ command as follows:
2634
2635    snit::type dog {
2636        delegate method save using {saverec %s}
2637    }
2638
2639The __%s__ is replaced with the instance name when the __save__ method
2640is called; any additional arguments are the appended to the resulting command\.
2641
2642The __using__ clause understands a number of other %\-conversions; in
2643addition to the instance name, you can substitute in the method name
2644\(__%m__\), the type name \(__%t__\), the instance namespace \(__%n__\),
2645the Tk window name \(__%w__\), and, if a component or typecomponent name was
2646given in the __delegate__ statement, the component's object command
2647\(__%c__\)\.
2648
2649## <a name='subsection118'></a>How can I delegate a method to a type component object?
2650
2651Just exactly as you would to a component object\. The __delegate method__
2652statement accepts both component and type component names in its __to__
2653clause\.
2654
2655## <a name='subsection119'></a>How can I delegate a type method to a type component object?
2656
2657Use the __delegate typemethod__ statement\. It works like __delegate
2658method__, with these differences: first, it defines a type method instead of
2659an instance method; second, the __using__ clause ignores the __%s__,
2660__%n__, and __%w__ %\-conversions\.
2661
2662Naturally, you can't delegate a type method to an instance component\.\.\.Snit
2663wouldn't know which instance should receive it\.
2664
2665## <a name='subsection120'></a>How can I delegate an option to a component object?
2666
2667The first question in this section \(see [DELEGATION](#section16)\) shows one
2668way to delegate an option to a component; but this pattern occurs often enough
2669that Snit makes it easy\. For example, every __tail__ object has a
2670__\-length__ option; we want to allow the creator of a __dog__ object to
2671set the tail's length\. We can do this:
2672
2673    % snit::type dog {
2674        delegate option -length to mytail
2675
2676        constructor {args} {
2677            install mytail using tail %AUTO% -partof $self
2678            $self configurelist $args
2679        }
2680    }
2681    ::dog
2682    % snit::type tail {
2683        option -partof
2684        option -length 5
2685    }
2686    ::tail
2687    % dog spot -length 7
2688    ::spot
2689    % spot cget -length
2690    7
2691
2692This produces nearly the same result as the __\-configuremethod__ and
2693__\-cgetmethod__ shown under the first question in this section: whenever a
2694__dog__ object's __\-length__ option is set or retrieved, the underlying
2695__tail__ object's option is set or retrieved in turn\.
2696
2697Note that you can define an option name using the __option__ statement, or
2698you can define it using __delegate__; you can't do both\.
2699
2700## <a name='subsection121'></a>Can I delegate to an option with a different name?
2701
2702In the previous answer we delegated the __dog__'s __\-length__ option
2703down to its __tail__\. This is, of course, wrong\. The dog has a length, and
2704the tail has a length, and they are different\. What we'd really like to do is
2705give the __dog__ a __\-taillength__ option, but delegate it to the
2706__tail__'s __\-length__ option:
2707
2708    snit::type dog {
2709        delegate option -taillength to mytail as -length
2710
2711        constructor {args} {
2712            set mytail [tail %AUTO% -partof $self]
2713            $self configurelist $args
2714        }
2715    }
2716
2717## <a name='subsection122'></a>How can I delegate any unrecognized method or option to a component object?
2718
2719It may happen that a Snit object gets most of its behavior from one of its
2720components\. This often happens with __snit::widgetadaptors__, for example,
2721where we wish to slightly the modify the behavior of an existing widget\. To
2722carry on with our __dog__ example, however, suppose that we have a
2723__snit::type__ called __animal__ that implements a variety of animal
2724behaviors\-\-moving, eating, sleeping, and so forth\. We want our __dog__
2725objects to inherit these same behaviors, while adding dog\-like behaviors of its
2726own\. Here's how we can give a __dog__ methods and options of its own while
2727delegating all other methods and options to its __animal__ component:
2728
2729    snit::type dog {
2730        delegate option * to animal
2731        delegate method * to animal
2732
2733        option -akc 0
2734
2735        constructor {args} {
2736            install animal using animal %AUTO% -name $self
2737            $self configurelist $args
2738        }
2739
2740        method wag {} {
2741            return "$self wags its tail"
2742        }
2743    }
2744
2745That's it\. A __dog__ is now an __animal__ that has a __\-akc__ option
2746and can __wag__ its tail\.
2747
2748Note that we don't need to specify the full list of method names or option names
2749that __animal__ will receive\. It gets anything __dog__ doesn't
2750recognize\-\-and if it doesn't recognize it either, it will simply throw an error,
2751just as it should\.
2752
2753You can also delegate all unknown type methods to a type component using
2754__delegate typemethod \*__\.
2755
2756## <a name='subsection123'></a>How can I delegate all but certain methods or options to a component?
2757
2758In the previous answer, we said that every __dog__ is an __animal__ by
2759delegating all unknown methods and options to the __animal__ component\. But
2760what if the __animal__ type has some methods or options that we'd like to
2761suppress?
2762
2763One solution is to explicitly delegate all the options and methods, and forgo
2764the convenience of __delegate method \*__ and __delegate option \*__\. But
2765if we wish to suppress only a few options or methods, there's an easier way:
2766
2767    snit::type dog {
2768        delegate option * to animal except -numlegs
2769        delegate method * to animal except {fly climb}
2770
2771        # ...
2772
2773        constructor {args} {
2774            install animal using animal %AUTO% -name $self -numlegs 4
2775            $self configurelist $args
2776        }
2777
2778        # ...
2779    }
2780
2781Dogs have four legs, so we specify that explicitly when we create the
2782__animal__ component, and explicitly exclude __\-numlegs__ from the set
2783of delegated options\. Similarly, dogs can neither __fly__ nor __climb__,
2784so we exclude those __animal__ methods as shown\.
2785
2786## <a name='subsection124'></a>Can a hierarchical method be delegated?
2787
2788Yes; just specify multiple words in the delegated method's name:
2789
2790    snit::type tail {
2791        method wag {} {return "Wag, wag"}
2792        method droop {} {return "Droop, droop"}
2793    }
2794
2795    snit::type dog {
2796        delegate method {tail wag} to mytail
2797        delegate method {tail droop} to mytail
2798
2799        # ...
2800
2801        constructor {args} {
2802            install mytail using tail %AUTO%
2803            $self configurelist $args
2804        }
2805
2806        # ...
2807    }
2808
2809Unrecognized hierarchical methods can also be delegated; the following code
2810delegates all subcommands of the "tail" method to the "mytail" component:
2811
2812    snit::type dog {
2813        delegate method {tail *} to mytail
2814
2815        # ...
2816    }
2817
2818# <a name='section17'></a>WIDGETS
2819
2820## <a name='subsection125'></a>What is a snit::widget?
2821
2822A __snit::widget__ is the Snit version of what Tcl programmers usually call
2823a *megawidget*: a widget\-like object usually consisting of one or more Tk
2824widgets all contained within a Tk frame\.
2825
2826A __snit::widget__ is also a special kind of __snit::type__\. Just about
2827everything in this FAQ list that relates to __snit::types__ also applies to
2828__snit::widgets__\.
2829
2830## <a name='subsection126'></a>How do I define a snit::widget?
2831
2832__snit::widgets__ are defined using the __snit::widget__ command, just
2833as __snit::types__ are defined by the __snit::type__ command\.
2834
2835The body of the definition can contain all of the same kinds of statements, plus
2836a couple of others which will be mentioned below\.
2837
2838## <a name='subsection127'></a>How do snit::widgets differ from snit::types?
2839
2840  - The name of an instance of a __snit::type__ can be any valid Tcl command
2841    name, in any namespace\. The name of an instance of a __snit::widget__
2842    must be a valid Tk widget name, and its parent widget must already exist\.
2843
2844  - An instance of a __snit::type__ can be destroyed by calling its
2845    __destroy__ method\. Instances of a __snit::widget__ have no destroy
2846    method; use the Tk __destroy__ command instead\.
2847
2848  - Every instance of a __snit::widget__ has one predefined component called
2849    its __hull__ component\. The hull is usually a Tk
2850    __[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__ or __toplevel__ widget;
2851    any other widgets created as part of the __snit::widget__ will usually
2852    be contained within the hull\.
2853
2854  - __snit::widget__s can have their options receive default values from
2855    [THE TK OPTION DATABASE](#section19)\.
2856
2857## <a name='subsection128'></a>What is a hull component?
2858
2859Snit can't create a Tk widget object; only Tk can do that\. Thus, every instance
2860of a __snit::widget__ must be wrapped around a genuine Tk widget; this Tk
2861widget is called the *hull component*\. Snit effectively piggybacks the
2862behavior you define \(methods, options, and so forth\) on top of the hull
2863component so that the whole thing behaves like a standard Tk widget\.
2864
2865For __snit::widget__s the hull component must be a Tk widget that defines
2866the __\-class__ option\.
2867
2868__snit::widgetadaptor__s differ from __snit::widget__s chiefly in that
2869any kind of widget can be used as the hull component; see [WIDGET
2870ADAPTORS](#section18)\.
2871
2872## <a name='subsection129'></a>How can I set the hull type for a snit::widget?
2873
2874A __snit::widget__'s hull component will usually be a Tk
2875__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__ widget; however, it may be any
2876Tk widget that defines the __\-class__ option\. You can explicitly choose the
2877hull type you prefer by including the __hulltype__ command in the widget
2878definition:
2879
2880    snit::widget mytoplevel {
2881        hulltype toplevel
2882
2883        # ...
2884    }
2885
2886If no __hulltype__ command appears, the hull will be a
2887__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__\.
2888
2889By default, Snit recognizes the following hull types: the Tk widgets
2890__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__, __labelframe__,
2891__toplevel__, and the Tile widgets __ttk::frame__,
2892__ttk::labelframe__, and __ttk::toplevel__\. To enable the use of some
2893other kind of widget as the hull type, you can __lappend__ the widget
2894command to the variable __snit::hulltypes__ \(always provided the widget
2895defines the __\-class__ option\. For example, suppose Tk gets a new widget
2896type called a __prettyframe__:
2897
2898    lappend snit::hulltypes prettyframe
2899
2900    snit::widget mywidget {
2901        hulltype prettyframe
2902
2903        # ...
2904    }
2905
2906## <a name='subsection130'></a>How should I name widgets which are components of a snit::widget?
2907
2908Every widget, whether a genuine Tk widget or a Snit megawidget, has to have a
2909valid Tk window name\. When a __snit::widget__ is first created, its instance
2910name, __self__, is a Tk window name; however, if the __snit::widget__ is
2911used as the hull component by a __snit::widgetadaptor__ its instance name
2912will be changed to something else\. For this reason, every __snit::widget__
2913method, constructor, destructor, and so forth is passed another implicit
2914argument, __win__, which is the window name of the megawidget\. Any children
2915should be named using __win__ as the root\.
2916
2917Thus, suppose you're writing a toolbar widget, a frame consisting of a number of
2918buttons placed side\-by\-side\. It might look something like this:
2919
2920    snit::widget toolbar {
2921        delegate option * to hull
2922
2923        constructor {args} {
2924            button $win.open -text Open -command [mymethod open]
2925            button $win.save -text Save -command [mymethod save]
2926
2927            # ....
2928
2929            $self configurelist $args
2930
2931        }
2932    }
2933
2934See also the question on renaming objects, toward the top of this file\.
2935
2936# <a name='section18'></a>WIDGET ADAPTORS
2937
2938## <a name='subsection131'></a>What is a snit::widgetadaptor?
2939
2940A __snit::widgetadaptor__ is a kind of __snit::widget__\. Whereas a
2941__snit::widget__'s hull is automatically created and is always a Tk frame, a
2942__snit::widgetadaptor__ can be based on any Tk widget\-\-or on any Snit
2943megawidget, or even \(with luck\) on megawidgets defined using some other package\.
2944
2945It's called a *widget adaptor* because it allows you to take an existing
2946widget and customize its behavior\.
2947
2948## <a name='subsection132'></a>How do I define a snit::widgetadaptor?
2949
2950Use the __snit::widgetadaptor__ command\. The definition for a
2951__snit::widgetadaptor__ looks just like that for a __snit::type__ or
2952__snit::widget__, except that the constructor must create and install the
2953hull component\.
2954
2955For example, the following code creates a read\-only text widget by the simple
2956device of turning its __insert__ and __delete__ methods into no\-ops\.
2957Then, we define new methods, __ins__ and __del__, which get delegated to
2958the hull component as __insert__ and __delete__\. Thus, we've adapted the
2959text widget and given it new behavior while still leaving it fundamentally a
2960text widget\.
2961
2962    ::snit::widgetadaptor rotext {
2963
2964        constructor {args} {
2965            # Create the text widget; turn off its insert cursor
2966            installhull using text -insertwidth 0
2967
2968            # Apply any options passed at creation time.
2969            $self configurelist $args
2970        }
2971
2972        # Disable the text widget's insert and delete methods, to
2973        # make this readonly.
2974        method insert {args} {}
2975        method delete {args} {}
2976
2977        # Enable ins and del as synonyms, so the program can insert and
2978        # delete.
2979        delegate method ins to hull as insert
2980        delegate method del to hull as delete
2981
2982        # Pass all other methods and options to the real text widget, so
2983        # that the remaining behavior is as expected.
2984        delegate method * to hull
2985        delegate option * to hull
2986    }
2987
2988The most important part is in the constructor\. Whereas __snit::widget__
2989creates the hull for you, __snit::widgetadaptor__ cannot \-\- it doesn't know
2990what kind of widget you want\. So the first thing the constructor does is create
2991the hull component \(a Tk text widget in this case\), and then installs it using
2992the __installhull__ command\.
2993
2994*Note:* There is no instance command until you create one by installing a hull
2995component\. Any attempt to pass methods to __$self__ prior to calling
2996__installhull__ will fail\.
2997
2998## <a name='subsection133'></a>Can I adapt a widget created elsewhere in the program?
2999
3000Yes\.
3001
3002At times, it can be convenient to adapt a pre\-existing widget instead of
3003creating your own\. For example, the Bwidget __PagesManager__ widget manages
3004a set of __[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__ widgets, only one of
3005which is visible at a time\. The application chooses which
3006__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__ is visible\. All of the These
3007__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__s are created by the
3008__PagesManager__ itself, using its __add__ method\. It's convenient to
3009adapt these frames to do what we'd like them to do\.
3010
3011In a case like this, the Tk widget will already exist when the
3012__snit::widgetadaptor__ is created\. Snit provides an alternate form of the
3013__installhull__ command for this purpose:
3014
3015    snit::widgetadaptor pageadaptor {
3016        constructor {args} {
3017            # The widget already exists; just install it.
3018            installhull $win
3019
3020            # ...
3021        }
3022    }
3023
3024## <a name='subsection134'></a>Can I adapt another megawidget?
3025
3026Maybe\. If the other megawidget is a __snit::widget__ or
3027__snit::widgetadaptor__, then yes\. If it isn't then, again, maybe\. You'll
3028have to try it and see\. You're most likely to have trouble with widget
3029destruction\-\-you have to make sure that your megawidget code receives the
3030__<Destroy>__ event before the megawidget you're adapting does\.
3031
3032# <a name='section19'></a>THE TK OPTION DATABASE
3033
3034## <a name='subsection135'></a>What is the Tk option database?
3035
3036The Tk option database is a database of default option values maintained by Tk
3037itself; every Tk application has one\. The concept of the option database derives
3038from something called the X Windows resource database; however, the option
3039database is available in every Tk implementation, including those which do not
3040use the X Windows system \(e\.g\., Microsoft Windows\)\.
3041
3042Full details about the Tk option database are beyond the scope of this document;
3043both *Practical Programming in Tcl and Tk* by Welch, Jones, and Hobbs, and
3044*Effective Tcl/Tk Programming* by Harrison and McClennan\., have good
3045introductions to it\.
3046
3047Snit is implemented so that most of the time it will simply do the right thing
3048with respect to the option database, provided that the widget developer does the
3049right thing by Snit\. The body of this section goes into great deal about what
3050Snit requires\. The following is a brief statement of the requirements, for
3051reference\.
3052
3053  - If the widget's default widget class is not what is desired, set it
3054    explicitly using the __widgetclass__ statement in the widget definition\.
3055
3056  - When defining or delegating options, specify the resource and class names
3057    explicitly when necessary\.
3058
3059  - Use the __installhull using__ command to create and install the hull for
3060    __snit::widgetadaptor__s\.
3061
3062  - Use the __install__ command to create and install all components which
3063    are widgets\.
3064
3065  - Use the __install__ command to create and install components which
3066    aren't widgets if you'd like them to receive option values from the option
3067    database\.
3068
3069The interaction of Tk widgets with the option database is a complex thing; the
3070interaction of Snit with the option database is even more so, and repays
3071attention to detail\.
3072
3073## <a name='subsection136'></a>Do snit::types use the Tk option database?
3074
3075No, they don't; querying the option database requires a Tk window name, and
3076__snit::type__s don't have one\.
3077
3078If you create an instance of a __snit::type__ as a component of a
3079__snit::widget__ or __snit::widgetadaptor__, on the other hand, and if
3080any options are delegated to the component, and if you use __install__ to
3081create and install it, then the megawidget will query the option database on the
3082__snit::type__'s behalf\. This might or might not be what you want, so take
3083care\.
3084
3085## <a name='subsection137'></a>What is my snit::widget's widget class?
3086
3087Every Tk widget has a "widget class": a name that is used when adding option
3088settings to the database\. For Tk widgets, the widget class is the same as the
3089widget command name with an initial capital\. For example, the widget class of
3090the Tk __button__ widget is __Button__\.
3091
3092Similarly, the widget class of a __snit::widget__ defaults to the
3093unqualified type name with the first letter capitalized\. For example, the widget
3094class of
3095
3096    snit::widget ::mylibrary::scrolledText { ... }
3097
3098is __ScrolledText__\.
3099
3100The widget class can also be set explicitly using the __widgetclass__
3101statement within the __snit::widget__ definition:
3102
3103    snit::widget ::mylibrary::scrolledText {
3104        widgetclass Text
3105
3106        # ...
3107    }
3108
3109The above definition says that a __scrolledText__ megawidget has the same
3110widget class as an ordinary __[text](\.\./\.\./\.\./\.\./index\.md\#text)__
3111widget\. This might or might not be a good idea, depending on how the rest of the
3112megawidget is defined, and how its options are delegated\.
3113
3114## <a name='subsection138'></a>What is my snit::widgetadaptor's widget class?
3115
3116The widget class of a __snit::widgetadaptor__ is just the widget class of
3117its hull widget; Snit has no control over this\.
3118
3119Note that the widget class can be changed only for
3120__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__ and __toplevel__ widgets,
3121which is why these are the valid hull types for __snit::widget__s\.
3122
3123Try to use __snit::widgetadaptor__s only to make small modifications to
3124another widget's behavior\. Then, it will usually not make sense to change the
3125widget's widget class anyway\.
3126
3127## <a name='subsection139'></a>What are option resource and class names?
3128
3129Every Tk widget option has three names: the option name, the resource name, and
3130the class name\. The option name begins with a hyphen and is all lowercase; it's
3131used when creating widgets, and with the __configure__ and __cget__
3132commands\.
3133
3134The resource and class names are used to initialize option default values by
3135querying the option database\. The resource name is usually just the option name
3136minus the hyphen, but may contain uppercase letters at word boundaries; the
3137class name is usually just the resource name with an initial capital, but not
3138always\. For example, here are the option, resource, and class names for several
3139Tk __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget options:
3140
3141    -background         background         Background
3142    -borderwidth        borderWidth        BorderWidth
3143    -insertborderwidth  insertBorderWidth  BorderWidth
3144    -padx               padX               Pad
3145
3146As is easily seen, sometimes the resource and class names can be inferred from
3147the option name, but not always\.
3148
3149## <a name='subsection140'></a>What are the resource and class names for my megawidget's options?
3150
3151For options implicitly delegated to a component using __delegate option \*__,
3152the resource and class names will be exactly those defined by the component\. The
3153__configure__ method returns these names, along with the option's default
3154and current values:
3155
3156    % snit::widget mytext {
3157        delegate option * to text
3158
3159        constructor {args} {
3160            install text using text .text
3161            # ...
3162        }
3163
3164        # ...
3165    }
3166    ::mytext
3167    % mytext .text
3168    .text
3169    % .text configure -padx
3170    -padx padX Pad 1 1
3171    %
3172
3173For all other options \(whether locally defined or explicitly delegated\), the
3174resource and class names can be defined explicitly, or they can be allowed to
3175have default values\.
3176
3177By default, the resource name is just the option name minus the hyphen; the the
3178class name is just the option name with an initial capital letter\. For example,
3179suppose we explicitly delegate "\-padx":
3180
3181    % snit::widget mytext {
3182        option -myvalue 5
3183
3184        delegate option -padx to text
3185        delegate option * to text
3186
3187        constructor {args} {
3188            install text using text .text
3189            # ...
3190        }
3191
3192        # ...
3193    }
3194    ::mytext
3195    % mytext .text
3196    .text
3197    % .text configure -myvalue
3198    -myvalue myvalue Myvalue 5 5
3199    % .text configure -padx
3200    -padx padx Padx 1 1
3201    %
3202
3203Here the resource and class names are chosen using the default rules\. Often
3204these rules are sufficient, but in the case of "\-padx" we'd most likely prefer
3205that the option's resource and class names are the same as for the built\-in Tk
3206widgets\. This is easily done:
3207
3208    % snit::widget mytext {
3209        delegate option {-padx padX Pad} to text
3210
3211        # ...
3212    }
3213    ::mytext
3214    % mytext .text
3215    .text
3216    % .text configure -padx
3217    -padx padX Pad 1 1
3218    %
3219
3220## <a name='subsection141'></a>How does Snit initialize my megawidget's locally\-defined options?
3221
3222The option database is queried for each of the megawidget's locally\-defined
3223options, using the option's resource and class name\. If the result isn't "",
3224then it replaces the default value given in widget definition\. In either case,
3225the default can be overridden by the caller\. For example,
3226
3227    option add *Mywidget.texture pebbled
3228
3229    snit::widget mywidget {
3230        option -texture smooth
3231        # ...
3232    }
3233
3234    mywidget .mywidget -texture greasy
3235
3236Here, __\-texture__ would normally default to "smooth", but because of the
3237entry added to the option database it defaults to "pebbled"\. However, the caller
3238has explicitly overridden the default, and so the new widget will be "greasy"\.
3239
3240## <a name='subsection142'></a>How does Snit initialize delegated options?
3241
3242That depends on whether the options are delegated to the hull, or to some other
3243component\.
3244
3245## <a name='subsection143'></a>How does Snit initialize options delegated to the hull?
3246
3247A __snit::widget__'s hull is a widget, and given that its class has been set
3248it is expected to query the option database for itself\. The only exception
3249concerns options that are delegated to it with a different name\. Consider the
3250following code:
3251
3252    option add *Mywidget.borderWidth 5
3253    option add *Mywidget.relief sunken
3254    option add *Mywidget.hullbackground red
3255    option add *Mywidget.background green
3256
3257    snit::widget mywidget {
3258        delegate option -borderwidth to hull
3259        delegate option -hullbackground to hull as -background
3260        delegate option * to hull
3261        # ...
3262    }
3263
3264    mywidget .mywidget
3265
3266    set A [.mywidget cget -relief]
3267    set B [.mywidget cget -hullbackground]
3268    set C [.mywidget cget -background]
3269    set D [.mywidget cget -borderwidth]
3270
3271The question is, what are the values of variables A, B, C and D?
3272
3273The value of A is "sunken"\. The hull is a Tk frame which has been given the
3274widget class __Mywidget__; it will automatically query the option database
3275and pick up this value\. Since the __\-relief__ option is implicitly delegated
3276to the hull, Snit takes no action\.
3277
3278The value of B is "red"\. The hull will automatically pick up the value "green"
3279for its __\-background__ option, just as it picked up the __\-relief__
3280value\. However, Snit knows that __\-hullbackground__ is mapped to the hull's
3281__\-background__ option; hence, it queries the option database for
3282__\-hullbackground__ and gets "red" and updates the hull accordingly\.
3283
3284The value of C is also "red", because __\-background__ is implicitly
3285delegated to the hull; thus, retrieving it is the same as retrieving
3286__\-hullbackground__\. Note that this case is unusual; the __\-background__
3287option should probably have been excluded using the delegate statement's
3288__except__ clause, or \(more likely\) delegated to some other component\.
3289
3290The value of D is "5", but not for the reason you think\. Note that as it is
3291defined above, the resource name for __\-borderwidth__ defaults to
3292__borderwidth__, whereas the option database entry is __borderWidth__,
3293in accordance with the standard Tk naming for this option\. As with
3294__\-relief__, the hull picks up its own __\-borderwidth__ option before
3295Snit does anything\. Because the option is delegated under its own name, Snit
3296assumes that the correct thing has happened, and doesn't worry about it any
3297further\. To avoid confusion, the __\-borderwidth__ option should have been
3298delegated like this:
3299
3300    delegate option {-borderwidth borderWidth BorderWidth} to hull
3301
3302For __snit::widgetadaptor__s, the case is somewhat altered\. Widget adaptors
3303retain the widget class of their hull, and the hull is not created automatically
3304by Snit\. Instead, the __snit::widgetadaptor__ must call __installhull__
3305in its constructor\. The normal way to do this is as follows:
3306
3307    snit::widgetadaptor mywidget {
3308        # ...
3309        constructor {args} {
3310            # ...
3311            installhull using text -foreground white
3312            # ...
3313        }
3314        # ...
3315    }
3316
3317In this case, the __installhull__ command will create the hull using a
3318command like this:
3319
3320    set hull [text $win -foreground white]
3321
3322The hull is a __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget, so its
3323widget class is __Text__\. Just as with __snit::widget__ hulls, Snit
3324assumes that it will pick up all of its normal option values automatically,
3325without help from Snit\. Options delegated from a different name are initialized
3326from the option database in the same way as described above\.
3327
3328In earlier versions of Snit, __snit::widgetadaptor__s were expected to call
3329__installhull__ like this:
3330
3331    installhull [text $win -foreground white]
3332
3333This form still works\-\-but Snit will not query the option database as described
3334above\.
3335
3336## <a name='subsection144'></a>How does Snit initialize options delegated to other components?
3337
3338For hull components, Snit assumes that Tk will do most of the work
3339automatically\. Non\-hull components are somewhat more complicated, because they
3340are matched against the option database twice\.
3341
3342A component widget remains a widget still, and is therefore initialized from the
3343option database in the usual way\. A
3344__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget remains a
3345__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget whether it is a component
3346of a megawidget or not, and will be created as such\.
3347
3348But then, the option database is queried for all options delegated to the
3349component, and the component is initialized accordingly\-\-provided that the
3350__install__ command is used to create it\.
3351
3352Before option database support was added to Snit, the usual way to create a
3353component was to simply create it in the constructor and assign its command name
3354to the component variable:
3355
3356    snit::widget mywidget {
3357        delegate option -background to myComp
3358
3359        constructor {args} {
3360            set myComp [text $win.text -foreground black]
3361        }
3362    }
3363
3364The drawback of this method is that Snit has no opportunity to initialize the
3365component properly\. Hence, the following approach is now used:
3366
3367    snit::widget mywidget {
3368        delegate option -background to myComp
3369
3370        constructor {args} {
3371            install myComp using text $win.text -foreground black
3372        }
3373    }
3374
3375The __install__ command does the following:
3376
3377  - Builds a list of the options explicitly included in the __install__
3378    command\-\-in this case, __\-foreground__\.
3379
3380  - Queries the option database for all options delegated explicitly to the
3381    named component\.
3382
3383  - Creates the component using the specified command, after inserting into it a
3384    list of options and values read from the option database\. Thus, the
3385    explicitly included options \(like __\-foreground__\) will override
3386    anything read from the option database\.
3387
3388  - If the widget definition implicitly delegated options to the component using
3389    __delegate option \*__, then Snit calls the newly created component's
3390    __configure__ method to receive a list of all of the component's
3391    options\. From this Snit builds a list of options implicitly delegated to the
3392    component which were not explicitly included in the __install__ command\.
3393    For all such options, Snit queries the option database and configures the
3394    component accordingly\.
3395
3396You don't really need to know all of this; just use __install__ to install
3397your components, and Snit will try to do the right thing\.
3398
3399## <a name='subsection145'></a>What happens if I install a non\-widget as a component of widget?
3400
3401A __snit::type__ never queries the option database\. However, a
3402__snit::widget__ can have non\-widget components\. And if options are
3403delegated to those components, and if the __install__ command is used to
3404install those components, then they will be initialized from the option database
3405just as widget components are\.
3406
3407However, when used within a megawidget, __install__ assumes that the created
3408component uses a reasonably standard widget\-like creation syntax\. If it doesn't,
3409don't use __install__\.
3410
3411# <a name='section20'></a>ENSEMBLE COMMANDS
3412
3413## <a name='subsection146'></a>What is an ensemble command?
3414
3415An ensemble command is a command with subcommands\. Snit objects are all ensemble
3416commands; however, the term more usually refers to commands like the standard
3417Tcl commands __[string](\.\./\.\./\.\./\.\./index\.md\#string)__,
3418__[file](\.\./\.\./\.\./\.\./index\.md\#file)__, and __clock__\. In a sense,
3419these are singleton objects\-\-there's only one instance of them\.
3420
3421## <a name='subsection147'></a>How can I create an ensemble command using Snit?
3422
3423There are two ways\-\-as a __snit::type__, or as an instance of a
3424__snit::type__\.
3425
3426## <a name='subsection148'></a>How can I create an ensemble command using an instance of a snit::type?
3427
3428Define a type whose [INSTANCE METHODS](#section5) are the subcommands of
3429your ensemble command\. Then, create an instance of the type with the desired
3430name\.
3431
3432For example, the following code uses [DELEGATION](#section16) to create a
3433work\-alike for the standard __[string](\.\./\.\./\.\./\.\./index\.md\#string)__
3434command:
3435
3436    snit::type ::mynamespace::mystringtype {
3437        delegate method * to stringhandler
3438
3439        constructor {} {
3440            set stringhandler string
3441        }
3442    }
3443
3444    ::mynamespace::mystringtype mystring
3445
3446We create the type in a namespace, so that the type command is hidden; then we
3447create a single instance with the desired name\-\- __mystring__, in this case\.
3448
3449This method has two drawbacks\. First, it leaves the type command floating about\.
3450More seriously, your shiny new ensemble command will have __info__ and
3451__destroy__ subcommands that you probably have no use for\. But read on\.
3452
3453## <a name='subsection149'></a>How can I create an ensemble command using a snit::type?
3454
3455Define a type whose [TYPE METHODS](#section9) are the subcommands of your
3456ensemble command\.
3457
3458For example, the following code uses [DELEGATION](#section16) to create a
3459work\-alike for the standard __[string](\.\./\.\./\.\./\.\./index\.md\#string)__
3460command:
3461
3462    snit::type mystring {
3463        delegate typemethod * to stringhandler
3464
3465        typeconstructor {
3466            set stringhandler string
3467        }
3468    }
3469
3470Now the type command itself is your ensemble command\.
3471
3472This method has only one drawback, and though it's major, it's also
3473surmountable\. Your new ensemble command will have __create__, __info__
3474and __destroy__ subcommands you don't want\. And worse yet, since the
3475__create__ method can be implicit, users of your command will accidentally
3476be creating instances of your __mystring__ type if they should mispell one
3477of the subcommands\. The command will succeed\-\-the first time\-\-but won't do
3478what's wanted\. This is very bad\.
3479
3480The work around is to set some [PRAGMAS](#section21), as shown here:
3481
3482    snit::type mystring {
3483        pragma -hastypeinfo    no
3484        pragma -hastypedestroy no
3485        pragma -hasinstances   no
3486
3487        delegate typemethod * to stringhandler
3488
3489        typeconstructor {
3490            set stringhandler string
3491        }
3492    }
3493
3494Here we've used the __pragma__ statement to tell Snit that we don't want the
3495__info__ typemethod or the __destroy__ typemethod, and that our type has
3496no instances; this eliminates the __create__ typemethod and all related
3497code\. As a result, our ensemble command will be well\-behaved, with no unexpected
3498subcommands\.
3499
3500# <a name='section21'></a>PRAGMAS
3501
3502## <a name='subsection150'></a>What is a pragma?
3503
3504A pragma is an option you can set in your type definitions that affects how the
3505type is defined and how it works once it is defined\.
3506
3507## <a name='subsection151'></a>How do I set a pragma?
3508
3509Use the __pragma__ statement\. Each pragma is an option with a value; each
3510time you use the __pragma__ statement you can set one or more of them\.
3511
3512## <a name='subsection152'></a>How can I get rid of the "info" type method?
3513
3514Set the __\-hastypeinfo__ pragma to __no__:
3515
3516    snit::type dog {
3517        pragma -hastypeinfo no
3518        # ...
3519    }
3520
3521Snit will refrain from defining the __info__ type method\.
3522
3523## <a name='subsection153'></a>How can I get rid of the "destroy" type method?
3524
3525Set the __\-hastypedestroy__ pragma to __no__:
3526
3527    snit::type dog {
3528        pragma -hastypedestroy no
3529        # ...
3530    }
3531
3532Snit will refrain from defining the __destroy__ type method\.
3533
3534## <a name='subsection154'></a>How can I get rid of the "create" type method?
3535
3536Set the __\-hasinstances__ pragma to __no__:
3537
3538    snit::type dog {
3539        pragma -hasinstances no
3540        # ...
3541    }
3542
3543Snit will refrain from defining the __create__ type method; if you call the
3544type command with an unknown method name, you'll get an error instead of a new
3545instance of the type\.
3546
3547This is useful if you wish to use a __snit::type__ to define an ensemble
3548command rather than a type with instances\.
3549
3550Pragmas __\-hastypemethods__ and __\-hasinstances__ cannot both be false
3551\(or there'd be nothing left\)\.
3552
3553## <a name='subsection155'></a>How can I get rid of type methods altogether?
3554
3555Normal Tk widget type commands don't have subcommands; all they do is create
3556widgets\-\-in Snit terms, the type command calls the __create__ type method
3557directly\. To get the same behavior from Snit, set the __\-hastypemethods__
3558pragma to __no__:
3559
3560    snit::type dog {
3561        pragma -hastypemethods no
3562        #...
3563    }
3564
3565    # Creates ::spot
3566    dog spot
3567
3568    # Tries to create an instance called ::create
3569    dog create spot
3570
3571Pragmas __\-hastypemethods__ and __\-hasinstances__ cannot both be false
3572\(or there'd be nothing left\)\.
3573
3574## <a name='subsection156'></a>Why can't I create an object that replaces an old object with the same name?
3575
3576Up until Snit 0\.95, you could use any name for an instance of a
3577__snit::type__, even if the name was already in use by some other object or
3578command\. You could do the following, for example:
3579
3580    snit::type dog { ... }
3581
3582    dog proc
3583
3584You now have a new dog named "proc", which is probably not something that you
3585really wanted to do\. As a result, Snit now throws an error if your chosen
3586instance name names an existing command\. To restore the old behavior, set the
3587__\-canreplace__ pragma to __yes__:
3588
3589    snit::type dog {
3590        pragma -canreplace yes
3591        # ...
3592    }
3593
3594## <a name='subsection157'></a>How can I make my simple type run faster?
3595
3596In Snit 1\.x, you can set the __\-simpledispatch__ pragma to __yes__\.
3597
3598Snit 1\.x method dispatch is both flexible and fast, but the flexibility comes
3599with a price\. If your type doesn't require the flexibility, the
3600__\-simpledispatch__ pragma allows you to substitute a simpler dispatch
3601mechanism that runs quite a bit faster\. The limitations are these:
3602
3603  - Methods cannot be delegated\.
3604
3605  - __uplevel__ and __upvar__ do not work as expected: the caller's
3606    scope is two levels up rather than one\.
3607
3608  - The option\-handling methods \(__cget__, __configure__, and
3609    __configurelist__\) are very slightly slower\.
3610
3611In Snit 2\.2, the __\-simpledispatch__ macro is obsolete, and ignored; all
3612Snit 2\.2 method dispatch is faster than Snit 1\.x's __\-simpledispatch__\.
3613
3614# <a name='section22'></a>MACROS
3615
3616## <a name='subsection158'></a>What is a macro?
3617
3618A Snit macro is nothing more than a Tcl proc that's defined in the Tcl
3619interpreter used to compile Snit type definitions\.
3620
3621## <a name='subsection159'></a>What are macros good for?
3622
3623You can use Snit macros to define new type definition syntax, and to support
3624conditional compilation\.
3625
3626## <a name='subsection160'></a>How do I do conditional compilation?
3627
3628Suppose you want your type to use a fast C extension if it's available;
3629otherwise, you'll fallback to a slower Tcl implementation\. You want to define
3630one set of methods in the first case, and another set in the second case\. But
3631how can your type definition know whether the fast C extension is available or
3632not?
3633
3634It's easily done\. Outside of any type definition, define a macro that returns 1
3635if the extension is available, and 0 otherwise:
3636
3637    if {$gotFastExtension} {
3638        snit::macro fastcode {} {return 1}
3639    } else {
3640        snit::macro fastcode {} {return 0}
3641    }
3642
3643Then, use your macro in your type definition:
3644
3645    snit::type dog {
3646
3647        if {[fastcode]} {
3648            # Fast methods
3649            method bark {} {...}
3650            method wagtail {} {...}
3651        } else {
3652            # Slow methods
3653            method bark {} {...}
3654            method wagtail {} {...}
3655        }
3656    }
3657
3658## <a name='subsection161'></a>How do I define new type definition syntax?
3659
3660Use a macro\. For example, your __snit::widget__'s __\-background__ option
3661should be propagated to a number of component widgets\. You could implement that
3662like this:
3663
3664    snit::widget mywidget {
3665        option -background -default white -configuremethod PropagateBackground
3666
3667        method PropagateBackground {option value} {
3668            $comp1 configure $option $value
3669            $comp2 configure $option $value
3670            $comp3 configure $option $value
3671        }
3672    }
3673
3674For one option, this is fine; if you've got a number of options, it becomes
3675tedious and error prone\. So package it as a macro:
3676
3677    snit::macro propagate {option "to" components} {
3678        option $option -configuremethod Propagate$option
3679
3680        set body "\n"
3681
3682        foreach comp $components {
3683            append body "\$$comp configure $option \$value\n"
3684        }
3685
3686        method Propagate$option {option value} $body
3687    }
3688
3689Then you can use it like this:
3690
3691    snit::widget mywidget {
3692        option -background default -white
3693        option -foreground default -black
3694
3695        propagate -background to {comp1 comp2 comp3}
3696        propagate -foreground to {comp1 comp2 comp3}
3697    }
3698
3699## <a name='subsection162'></a>Are there are restrictions on macro names?
3700
3701Yes, there are\. You can't redefine any standard Tcl commands or Snit type
3702definition statements\. You can use any other command name, including the name of
3703a previously defined macro\.
3704
3705If you're using Snit macros in your application, go ahead and name them in the
3706global namespace, as shown above\. But if you're using them to define types or
3707widgets for use by others, you should define your macros in the same namespace
3708as your types or widgets\. That way, they won't conflict with other people's
3709macros\.
3710
3711If my fancy __snit::widget__ is called __::mylib::mywidget__, for
3712example, then I should define my __propagate__ macro as
3713__::mylib::propagate__:
3714
3715    snit::macro mylib::propagate {option "to" components} { ... }
3716
3717    snit::widget ::mylib::mywidget {
3718        option -background default -white
3719        option -foreground default -black
3720
3721        mylib::propagate -background to {comp1 comp2 comp3}
3722        mylib::propagate -foreground to {comp1 comp2 comp3}
3723    }
3724
3725# <a name='section23'></a>Bugs, Ideas, Feedback
3726
3727This document, and the package it describes, will undoubtedly contain bugs and
3728other problems\. Please report such in the category *snit* of the [Tcllib
3729Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
3730for enhancements you may have for either package and/or documentation\.
3731
3732When proposing code changes, please provide *unified diffs*, i\.e the output of
3733__diff \-u__\.
3734
3735Note further that *attachments* are strongly preferred over inlined patches\.
3736Attachments can be made by going to the __Edit__ form of the ticket
3737immediately after its creation, and then using the left\-most button in the
3738secondary navigation bar\.
3739
3740# <a name='keywords'></a>KEYWORDS
3741
3742[BWidget](\.\./\.\./\.\./\.\./index\.md\#bwidget), [C\+\+](\.\./\.\./\.\./\.\./index\.md\#c\_),
3743[Incr Tcl](\.\./\.\./\.\./\.\./index\.md\#incr\_tcl),
3744[adaptors](\.\./\.\./\.\./\.\./index\.md\#adaptors),
3745[class](\.\./\.\./\.\./\.\./index\.md\#class), [mega
3746widget](\.\./\.\./\.\./\.\./index\.md\#mega\_widget),
3747[object](\.\./\.\./\.\./\.\./index\.md\#object), [object
3748oriented](\.\./\.\./\.\./\.\./index\.md\#object\_oriented),
3749[widget](\.\./\.\./\.\./\.\./index\.md\#widget), [widget
3750adaptors](\.\./\.\./\.\./\.\./index\.md\#widget\_adaptors)
3751
3752# <a name='category'></a>CATEGORY
3753
3754Programming tools
3755
3756# <a name='copyright'></a>COPYRIGHT
3757
3758Copyright &copy; 2003\-2006, by William H\. Duquette
3759