package require snit snit::type Dict { variable dictv method append {key args} { variable dictv return [eval ::dict append dictv [list $key] $args] } method exists {args} { variable dictv return [eval ::dict exists [list $dictv] $args] } method filter {ftype args} { variable dictv return [eval ::dict [list $dictv $ftype] $args] } method for {kv body} { variable dictv return [uplevel 1 ::dict for $kv $dictv $body] } method get {args} { variable dictv return [eval ::dict get [list $dictv] $args] } method incr {key {incr 1}} { variable dictv return [::dict incr dictv $key $incr] } method keys {{glob *}} { variable dictv return [eval ::dict keys [list $dictv] $glob] } method lappend {key args} { variable dictv return [eval ::dict lappend dictv [list $key] $args] } method remove {args} { variable dictv return [::set dictv [eval ::dict remove [list $dictv] $args]] } method replace {args} { variable dictv return [::set dictv [eval ::dict replace [list $dictv] $args]] } method set {args} { variable dictv return [::set dictv [eval ::dict set dictv $args]] } method size {} { variable dictv return [::dict size $dictv] } method unset {args} { variable dictv return [eval ::dict unset dictv $args] } method values {{glob *}} { variable dictv return [::dict values $dictv $glob] } method subdict {sub args} { variable dictv return [$self set [eval ::dict create $args]] } method serialize {} { variable dictv return $dictv } method restore {ser} { variable dictv eval dict set dictv $ser } constructor {args} { variable dictv ::set dictv [eval ::dict create $args] } destructor {} }
WHD: Two questions: why are you declaring dictv in every method? You don't need to. Second, why are you explicitly qualifying "::set"? You don't need to do that either.
CMcC: Answer 1) I think I should have to. It's been a while since I looked at snit's implementation, but how is the silent importation of instance variables achieved? Instance vars exist in namespaces, AFAIK they have to be qualified by namespace or explicitly declared. If Snit's doing the variable declarations itself, then there's an avoidable overhead.
I've checked the output. Snit declares all instance variables in all methods. I think this is needless overhead, detrimental to performance. I would rather it declare no variables but self, type, etc.
I note that the variable declaration for each instance variable is of the form: [::variable ${selfns}::options] ... is this strictly necessary? Aren't method invocations performed in the namespace context ${selfns} anyway? IOW, isn't [::variable options] equivalent to the snit-generated form?
Ah! No, from what I remember of looking at Snit, in fact the procs representing methods are defined in a per-class namespace, so my '::variable dict' in this context is actually incorrect! It's probably equivalent to referencing a class variable dict.
WHD: 1) It's true that there's an overhead to declaring the instance variables automatically in each method is an avoidable overhead. You avoid it by declaring them *only* in the methods that need them and not in the body of the type definition. But if you need it in each method, as you do here, it's a great convenience.
2) Snit redefines "variable"; the code you have here is correct. If you used "::variable", though, it would be wrong.
3) Yes, procs representing methods are defined in the type namespace and execute in that namespace. To have them execute in the instance namespace, I'd need to duplicate them for each instance. Faster, possibly, but you'd have lots more memory overhead per instance.
4) I still don't understand why you're qualifying "::set". The "set" method doesn't conflict with it.
See also: