Version 1 of tcl9var compatibility issues

Updated 2009-11-13 14:55:56 by wdb
if false {

wdb on page tcl9var, we discussed unification of namespaces of commands and variables. Main argument against it was broken compatibility to current variables.

Here a try to use it with source-compatibility to Tcl 8.x:

}

package require Tcl 8.5
# because of dict

namespace eval tcl9var {
  variable tcl9val {}
  namespace export tcl9var
}

proc tcl9var::handleVar {name {cmd get} args} {
  variable tcl9val
  if {$cmd in {set unset}} then {
    dict $cmd tcl9val $name {*}$args
  } else {
    dict $cmd $tcl9val $name {*}$args 
  }
}

proc tcl9var::tcl9var {name args} {
  variable tcl9val
  set ns [uplevel namespace current]
  if {$ns eq "::"} then {
    set n ::$name
  } else {
    set n ${ns}::$name
  }
  dict set tcl9val $n {*}$args
  uplevel 1 [list proc $name args {
      ::tcl9var::handleVar [
        namespace origin [lindex [info level 0] 0]
      ] {*}$args
    }]
  $name
}

namespace import tcl9var::tcl9var

if false {

As an example, we use a simple variable:

% tcl9var a apple
apple
% puts "my [a] is red"
my apple is red
% a set [a]tree
::obst {a apfel b birne} ::a appletree
% puts "my [a] is high"
my appletree is high
% 

In one way we can build a variable as a dictionary:

tcl9var fruit
% tcl9var fruit a apple
a apple
% tcl9var fruit o orange
a apple o orange
% fruit 
a apple o orange
% fruit get
a apple o orange
% fruit get a
apple
% fruit get o
orange
% fruit set o mango
::a appletree ::fruit {a apple o mango}
% fruit get o
mango

Care must be taken if the "raw value" of a variable has an odd number of elements -- then dict usage fails.

Compatibility issues

With usage as dict, we can introduce a special variable $ internally built as dictionary as follows:

% tcl9var $ start 0
start 0
% tcl9var $ end 10
start 0 end 10
% $ get start
0
% $ get end
10
% 
}

if false {

Now, the syntax $abc shall shall be expanded by proc expand$ to the appropriate call of variable $ above.

With this expansion of cmd lines, you can make things like $hello, or $hello(world), or $hello(world)(of_tcl_programming), i.e. true multi-dimensional arrays.

}

proc expand$ str {
  if {![regexp {[$]([[:alnum:]_]+)((?:[(].*[)])*)} $str m v b]} then {
    return $str
  }
  set matchStart [string first $m $str]
  set matchEnd $matchStart
  incr matchEnd [string length $m]
  incr matchStart -1
  append result [string range $str 0 $matchStart]\
    "\[$ get $v"
  foreach x [split [string trim [string map {( ""} $b] )] )] {
    append result " [list $x]"
  }
  append result \]\
    [expand$ [string range $str $matchEnd end]]
}

if false {

Example:

% expand$ {This $a stems from $your(garden)}
This [$ get a] stems from [$ get your garden]
% 
% expand$ {test call: $a(b)(c)(d)}
test call: [$ get a b c d]
% 

An appropriate procedure set can be defined as needed by backwards compatibility.

Consequences: syntax with $ works as usual.

Semantics of dict provided by variable methods. Shorter source code.

Unsolved problems: as $ is a procedure here, it cannot (yet) be local to a proc or apply close. Perhaps subject for a TIP? (I'm not sure.)

}

Category Suggestions | Category Concept