Posted to tcl by colin at Sun May 23 23:54:21 GMT 2010view raw

  1. # A combination of *dict with* and *apply*, this procedure creates a
  2. # new procedure scope populated with the values in the dictionary
  3. # variable. It then applies the lambdaTerm (anonymous procedure) in
  4. # this new scope. If the procedure completes normally, then any
  5. # changes made to variables in the dictionary are reflected back to
  6. # the dictionary variable, otherwise they are ignored. This provides
  7. # a transaction-style semantics whereby atomic updates to a
  8. # dictionary can be performed. This procedure can also be useful for
  9. # implementing a variety of control constructs, such as mutable
  10. # closures.
  11. #
  12. proc apply {dictVar lambdaExpr args} {
  13. upvar 1 $dictVar dict
  14. set env $dict ;# copy
  15. lassign $lambdaExpr params body ns
  16. if {$ns eq ""} { set ns "::" }
  17. set body [format {
  18. upvar 1 env __env__
  19. dict with __env__ %s
  20. } [list $body]]
  21. set lambdaExpr [list $params $body $ns]
  22. set rc [catch { ::apply $lambdaExpr {*}$args } ret opts]
  23. if {$rc == 0} {
  24. # Copy back any updates
  25. set dict $env
  26. }
  27. return -options $opts $ret
  28. }