** Synopsis ** A (mostly) better alternative to [namespace ensemble]: ====== oo::object create stash oo::objdefine stash { variable Stash method set {name val} { set Stash($name) $val } method get {name} { return $Stash($name) } } ====== A few things are noteworthy: * we didn't define a [class]! [TclOO] lets us define `[oo::objdefine] method`s directly on any object. * methods don't get in the way of command resolution inside the object: we can call `set` without worrying that a `method set` exists. To call other commands within the ensemble, just use [my] * we have no control over the [object]'s [namespace]. This is mildly dissatisfying compared to ensembles, but [self namespace] is better than a hardcoded reference -- it makes each method copy&paste-portable to other objects ** Rationale ** Historically, [namespace ensemble]s have been plagued with one [Tcl Warts%|%wart]: command resolution starts in the ensemble's namespace. Thus, subcommands with names like `set` are problematic: ====== namespace eval stash { proc set {name val} { variable Stash set Stash($name) $val } proc get {name} { variable Stash return $Stash($name) } namespace export * namespace ensemble create } ====== This example will fail, because `stash set` accidentaly calls itself! This can be worked around by using `::set`, but such changes are ugly. And not just cosmetically: try extending an existing ensemble with a `set` method, or gracefully using [namespace path]. [TclOO] provides a neat solution to this: simply use an object. Anonymous comment 2016-05-02: The impact of this wart can be reduced somewhat with `-map`: ====== ... proc _set {name val} { ... namespace ensemble create -map {set _set get get} ====== [WHD]: Another way to convenient create an ensemble is to use a [snit::type] as a singleton. It's a namespace ensemble under the covers, but avoids the "set" problem described above, and allows easy delegation of methods. The main trick is to disable the creation of instances of the type: snit::type myensemble { pragma -hasinstances no typemethod set {key value} { ... } } ** TODO ** Nested ensemble objects (hint: `[oo::objdefine] forward`). More rationale? Link some of the wart discussions here for a solution (and clean them up). ** See Also ** * [TclOO Tricks], where this concept appears as a "Singleton". * [Inspecting TclOO] is handy to see exactly what's defined on your object. * [Extending TclOO with metaclasses] might be relevant. * [namespace] and [namespace ensemble] talk about some of these issues. * [Object method ensemble] is a different thing, but may be useful in conjunction. <>TclOO | Example