cmdr
Check-in [434ada2661]
Not logged in
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2018 Conference, Houston/TX, US, Oct 15-19
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Aug 20.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:officer - Extended class to accept the unique prefixes of the known command names for dispatch.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:434ada2661e8c6546ed369275eb69ec35fb12cc5
User & Date: andreask 2014-02-19 20:20:16
Context
2014-03-13
20:04
cmdr::validate - Tweaked the "integer" validation type to use decimal as internal representation, as we accept octal and hex as external strings. check-in: 47da046a26 user: andreask tags: trunk
2014-02-19
20:20
officer - Extended class to accept the unique prefixes of the known command names for dispatch. check-in: 434ada2661 user: andreask tags: trunk
2014-02-17
23:29
Excluded auto-added commands from categorized help. check-in: 7e77c5a0be user: andreask tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to officer.tcl.

76
77
78
79
80
81
82

83
84
85
86
87
88
89
...
123
124
125
126
127
128
129

130









131
132
133
134
135
136
137
138
139
140
141
142
...
315
316
317
318
319
320
321
322
323







324
325
326
327
328
329
330
...
336
337
338
339
340
341
342


343









344
345
346
347
348
349
350
...
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685

	my super: $super
	my name:  $name

	set myactions   $actions ; # Action spec for future initialization
	set myinit      no       ; # Dispatch map will be initialized lazily
	set mymap       {}       ; # Action map starts knowing nothing

	set mycommands  {}       ; # Ditto
	set myccommands {}       ; # Ditto, derived cache, see method CCommands.
	set mychildren  {}       ; # List of created subordinates.
	set myhandler   {}
	return
    }

................................................................................
	my Setup
	return [dict get $mymap default]
    }

    method lookup {name} {
	debug.cmdr/officer {}
	my Setup

	if {![dict exists $mymap a,$name]} {









	    return -code error \
		-errorcode [list CMDR ACTION UNKNOWN $name] \
		"Expected action name, got \"$name\""
	}
	return [dict get $mymap a,$name]
    }

    method find {words} {
	# Resolve chain of words (command name path) to the actor
	# responsible for that command, starting from the current
	# actor.  This is very much a convenience method built on top
	# of lookup (see above).
................................................................................
	my Def $name $handler
	return $handler
    }

    method Def {name handler} {
	# Make an action known to the dispatcher.
	dict set mymap last $name
	dict set mymap   a,$name $handler
	lappend mycommands $name







	return
    }

    method ValidateAsUnknown {name} {
	debug.cmdr/officer {}
	if {![dict exists $mymap a,$name]} return
	return -code error -errorcode {CMDR ACTION KNOWN} \
................................................................................
	    return -code error -errorcode {CMDR ACTION NO-LAST} \
		"Cannot be used as first command"
	}
	return [dict get $mymap last]
    }

    method Known {name} {


	return [dict exists $mymap a,$name]









    }

    # # ## ### ##### ######## #############
    ## Command dispatcher. Choose the subordinate and delegate.

    method do {args} {
	debug.cmdr/officer {}
................................................................................
	}
	return $help
    }

    # # ## ### ##### ######## #############

    variable myinit myactions mymap mycommands myccommands mychildren \
	myreplexit myhandler

    # # ## ### ##### ######## #############
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::officer 1.2







>







 







>
|
>
>
>
>
>
>
>
>
>
|
|
|
<
<







 







|

>
>
>
>
>
>
>







 







>
>
|
>
>
>
>
>
>
>
>
>







 







|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
...
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712

	my super: $super
	my name:  $name

	set myactions   $actions ; # Action spec for future initialization
	set myinit      no       ; # Dispatch map will be initialized lazily
	set mymap       {}       ; # Action map starts knowing nothing
	set mypmap      {}       ; # Ditto for the map of action abbreviations.
	set mycommands  {}       ; # Ditto
	set myccommands {}       ; # Ditto, derived cache, see method CCommands.
	set mychildren  {}       ; # List of created subordinates.
	set myhandler   {}
	return
    }

................................................................................
	my Setup
	return [dict get $mymap default]
    }

    method lookup {name} {
	debug.cmdr/officer {}
	my Setup
	# An exact action name has priority over any prefixes.
	if {[dict exists $mymap a,$name]} {
	    return [dict get $mymap a,$name]
	}
	# Accept any unique prefix.
	if {
	    [dict exists $mypmap $name] &&
	    ([llength [set hl [dict get $mypmap $name]]] == 1)
	} {
	    return [lindex $hl 0]
	}
	return -code error \
	    -errorcode [list CMDR ACTION UNKNOWN $name] \
	    "Expected action name, got \"$name\""


    }

    method find {words} {
	# Resolve chain of words (command name path) to the actor
	# responsible for that command, starting from the current
	# actor.  This is very much a convenience method built on top
	# of lookup (see above).
................................................................................
	my Def $name $handler
	return $handler
    }

    method Def {name handler} {
	# Make an action known to the dispatcher.
	dict set mymap last $name
	dict set mymap a,$name $handler
	lappend mycommands $name

	# Update the map of action prefixes
	set prefix {}
	foreach c [split $name {}] {
	    append prefix $c
	    dict lappend mypmap $prefix $handler
	}
	return
    }

    method ValidateAsUnknown {name} {
	debug.cmdr/officer {}
	if {![dict exists $mymap a,$name]} return
	return -code error -errorcode {CMDR ACTION KNOWN} \
................................................................................
	    return -code error -errorcode {CMDR ACTION NO-LAST} \
		"Cannot be used as first command"
	}
	return [dict get $mymap last]
    }

    method Known {name} {
	debug.cmdr/officer {}
	# Known exact action is good
	if {[dict exists $mymap a,$name]} { return 1 }
	debug.cmdr/officer {no action, maybe prefix}
	# Unknown prefix is bad
	if {![dict exists $mypmap $name]} { return 0 }
	debug.cmdr/officer {prefix, maybe ambiguous}
	# As is an ambiguous prefix
	if {[llength [dict get $mypmap $name]] > 1} { return 0 }
	debug.cmdr/officer {unique prefix}
	# Known unique prefix is good.
	return 1
    }

    # # ## ### ##### ######## #############
    ## Command dispatcher. Choose the subordinate and delegate.

    method do {args} {
	debug.cmdr/officer {}
................................................................................
	}
	return $help
    }

    # # ## ### ##### ######## #############

    variable myinit myactions mymap mycommands myccommands mychildren \
	myreplexit myhandler mypmap

    # # ## ### ##### ######## #############
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::officer 1.2