On Tuesday, July 19, 2022 at 2:22:08 PM UTC+2, aotto1 wrote:
> Hi,
>
> an *uplevel-proc* is an *proc* which evaluate the entire content
> *uplevel* → example:
>
> proc Format_Return_Error_Check {hdl err} {
> uplevel "Format_Error_Check $hdl $err ; set retM void"
> }
>
> This simulate a *CPP*-Macro like behavior in *TCL*.
Tcl has quite some nice features that can help to prevent duplicate code beyond putting it in a proc. Here are some that are crossing my mind.
1. uplevel
If you stick to your pattern, you are looking for [catch {uplevel 1 {...}} result options], then [dict incr options -level; return {*}$options $result].
You could even write your own proc "macro" that adds this wrapper to the code before actually creating the proc.
2. upvar
As uplevel has a performance penalty (cannot be optimized), upvar'ing well-known or passed variable names should be preferred over uplevel. The catch-wrapper is still needed for generic code.
3. inject code
Sometimes, I am using [proc name args [format {} $inject1 ...]]. I am using it for one-time-setup/config and also to prevent duplicate code.
Pro: Tcl sees a constant proc body and can fully optimize it.
Con: An extra level of escaping, but % is normally not a factor.
4. rewrite code
Just recently, I was injecting a code fix to a foreign proc while initializing my code. This pattern could be extended to rewrite "macros".
apply {{} {
set name this_proc
# build args like for proc
set args [lmap arg [info args $name] {
if {[info default $name $arg default]} {
list $arg $default
} else {
list $arg
}
}]
set body [info body $name]
# re-write to allow $client with parameters
# (braces around proc make my code doc scanner ignore this one)
{proc} $name $args [string map {{invoke $client } {invoke {*}$client }} $body]
log warn "$name was re-written!"
}}
Pro: Tcl sees a constant proc body and can fully optimize it.
Con (for non-Tclers): Might not feel like the natural way of coding ;-)
5. eval
Instead of uplevel, do uplevel without context change: eval.
6. packages/libs
Iirc, there are also a few Tcl packages that hook in to do magic to your code. Others may have names at hand.
HTH
Martin