[Richard Suchenwirth] 2006-06-05 - "Environment" is understood here as a set of variables and their values, like many operating systems make available to processes (in Tcl, the [env] variable mirrors that). There may be situations when you want to provide a local environment from one [proc] A to another, B, without having to build a long argument list, nor having to use [global] variables. Other languages with lexical scoping, like [Lisp], have that as built-in feature, but here's a simple way how to do that in Tcl: a {name value name value...} list is wrapped, passed to the called function, which in turn unwraps it. You have to specify which variables shall go in, that's why I call it "controlled environment" :^) Usage ("name" being a freely choosable variable name): env name add var... ;# in the caller, who calls the callee with $name env name get ;# in the callee Only scalar variables can be wrapped. The callee gets copies of the variables which he can change at will, without influencing the "originals" in the caller. Both features mirror those of OS environment variables. ====== proc env {_name mode args} { upvar 1 $_name var switch -- $mode { add {foreach n $args {lappend var $n [uplevel 1 set $n]}} get {foreach {n val} $var {uplevel 1 [list set $n $val]}} default {error "bad mode $mode, use add or get"} } } #-- Testing (the example should leave no question open): proc caller arg { set foo 42 set bar grill env e add arg foo bar callee 123 $e } proc callee {x e} { env e get foreach name [info vars] { lappend res $name=[set $name] } set res } puts [caller hello!] ====== which returns: x=123 {e=arg hello! foo 42 bar grill} foo=42 bar=grill arg=hello! See also [closures]. [NEM]: In particular, see [Simple Closures and Objects], which does a similar thing, but using ''[dict] with'' to restore the environment in the new scope. <> Example | Arts and crafts of Tcl-Tk programming