Here's a simple bit of code to extend any ensemble-like command by means of tcl8.5's namespace ensemble command. CMcC 6Mar2006
Larry Smith: stacking does a similar job.
package provide extend 1.0 package require Tcl 8.5 # extend a command with a new subcommand proc extend {cmd body} { if {![namespace exists ${cmd}]} { set wrapper [string map [list %C $cmd %B $body] { namespace eval %C {} rename %C %C::%C namespace eval %C { proc _unknown {junk subc args} { return [list %C::%C $subc] } namespace ensemble create -unknown %C::_unknown } }] } append wrapper [string map [list %C $cmd %B $body] { namespace eval %C { %B namespace export -clear * } }] uplevel 1 $wrapper }
Here's the file command extended with newer and newerthan subcommands:
extend file { proc newer {a b} { return [expr {[file mtime $a] > [file mtime $b]}] } proc newerthan {mtime path} { return [expr {[file exists $path] && ([file mtime $path] > $mtime)}] } }
Here's the dict command extended with the modify subcommand:
# extra useful dict commands extend dict { proc modify {var args} { upvar 1 $var dvar foreach {name val} $args { dict set dvar $name $val } } }
LV So, this seems like a nice bit of functionality. Would it be useful enough to include either in Tcl itself or at least Tcllib?
quick hacks ?
AMG: See also my [dict getnull] example in [dict get].
In a comp.lang.tcl posting dated Fri, 04 Apr 2014 09:25:30 DKF posted an example of using the ensemble's -unknown parameter to lazily apply extensions. A version of extend using this technique:
proc extend {ens script} { namespace eval $ens [concat { proc _unknown {ens cmd args} { if {$cmd in [namespace eval ::${ens} {::info commands}]} { set map [namespace ensemble configure $ens -map] dict set map $cmd ::${ens}::$cmd namespace ensemble configure $ens -map $map } return "" ;# back to namespace ensemble dispatch ;# which will error appropriately if the cmd doesn't exist } } \; $script] namespace ensemble configure $ens -unknown ${ens}::_unknown }
Note that new extensions defined in this way will not appear in the ensemble's map until they are used, so the default error message is misleading.