**list ensemble** [bll] 2018-7-24: An exercise in learning about namespace ensemble. This is an implementation (one possible anyways) of the list ensemble command. All of the usual list commands are still present. List creation is backwards compatible by using the namespace ensemble -unknown handler. It seems to work, but has not been tested extensively. I had a lot of trouble creating this. namespace ensemble seems to be very sensitive. Many things I tried did not work as expected from reading the wiki page on namespace ensemble. The documentation could use some updating to be more precise and could use some quality examples. ====== #!/usr/bin/tclsh # # Originally written by Brad Lanam # In the public domain # rename ::list ::_list namespace eval ::list { set cmdlist [::_list append assign index insert length map range] ::lappend cmdlist repeat replace reverse search set sort ::lappend cmdlist create size namespace export {*}$cmdlist namespace ensemble create \ -unknown ::list::_unknown \ -subcommands $cmdlist # I also tried -map {size length}, but that did not work out. # I suppose there must be a way to get -map to work, but I could not find it. variable _cflag false variable _csave {} proc _unknown { args } { variable _cflag variable _csave # Unfortunately, the unknown handler is very specific to # a namespace ensemble and is not a general handler. # argument index 1 is stripped out and lost. # Have to jump through some hoops here. # There's a lot of weirdness here # " If the -unknown handler returns anything else, # it is interpreted as a command prefix" # does not seem to be true. 'return create' does not work, # and in fact, 'return create' fails to pass the appended argument list, # the create routine gets called, and errors out with a bad # subcommand error. # save the needed value for the create command set _csave [::lindex $args 1] set _cflag true return [::_list ::list create] } proc create { args } { variable _cflag variable _csave if { $_cflag } { # more weirdness, cannot seem to set and use local variables, or # even global variables. # I tried: # set val [::_list $_csave {*}$args] # set _csave {} # return $val # and it did not work. # Tried: # variable _tval # set _tval [::_list $_csave {*}$args] # set _csave {} # return $_tval # and it did not work. set _cflag false return [::_list $_csave {*}$args] } return [::_list {*}$args] } # for orthogonality... proc size { args } { return [::llength {*}$args] } proc append { args } { return [uplevel 1 ::lappend {*}$args] } proc assign { args } { return [uplevel 1 ::lassign {*}$args] } proc index { args } { return [::lindex {*}$args] } proc insert { args } { return [::linsert {*}$args] } proc length { args } { return [::llength {*}$args] } proc map { args } { return [uplevel 1 ::lmap {*}$args] } proc range { args } { return [::lrange {*}$args] } proc repeat { args } { return [::lrepeat {*}$args] } proc replace { args } { return [::lreplace {*}$args] } proc reverse { args } { return [::lreverse {*}$args] } proc search { args } { return [::lsearch {*}$args] } proc set { args } { return [uplevel 1 ::lset {*}$args] } proc sort { args } { return [::lsort {*}{$args}] } } package provide listensemble 0.1 ====== [PL] 2018-07-24: You can make use of `ensemble create -map` like this: ====== namespace eval list { namespace export {[a-z]*} namespace ensemble create -map { create ::_list size ::llength append ::lappend assign ::lassign index ::lindex insert ::linsert length ::llength map ::lmap range ::lrange repeat ::lrepeat replace ::lreplace reverse ::lreverse search ::lsearch set ::lset sort ::lsort each ::foreach } } ====== <>Enter Category Here