dbohdan 2015-02-20: This little hack implements a piece of syntax resembling the
expr shorthand from
Jim Tcl in Tcl 8.x:
$(...). It does so by
tracing array reads from the array with the name
{} (an
empty string).
A kind of
double substitution is sadly unavoidable here. Basically,
subst is performed on an array index before it is passed to the
proc tracing it. This, together with the very syntax used for array indexing, means that you have to manually escape
$,
g and
() with a backslash in your expressions. This is rather error prone, which is why the author would recommend against using
arrexpr for anything but amusement.
Code
namespace eval ::arrexpr {
namespace export *
upvar #0 {} {}
set () {}
trace add variable {} {array read write unset} ::arrexpr::tracer
}
proc ::arrexpr::tracer {name index op} {
if {$name eq ""} {
global $name
switch -exact -- $op {
read {
array unset $name *
set ($index) [uplevel 1 [list expr $index]]
}
write {
error "not writable"
}
}
}
}
proc ::arrexpr::use {} {
uplevel 1 {
upvar #0 {} {}
}
}
Use examples
source arrexpr.tcl
puts $(2 + 2)
proc vector-length {a b} {
::arrexpr::use
return $(sqrt\($a * $a + $b * $b\))
}
puts [vector-length 1 1]
puts $("hello")
# Double substitution. :-(
set a 1
set b a
puts $($$b) ;# prints "1"
set value 5
puts $(\$value > 0 ? "positive" : "zero or negative")