0

Here is a code example:

set my_ref {$undefined_array(some_key)}
set my_val [subst $my_ref]

which returns:

can't read "undefined_array(some_key)": no such variable
    while executing
"subst $my_ref"

According to http://wiki.tcl.tk/1501

Looks like there is no way to catch this right now

Eugeniu Rosca
  • 5,177
  • 16
  • 45

1 Answers1

3

When subst attempts to perform substitutions on the text you gave it, it needs an existing variable with a matching name. If no such variable exists, subst throws a TCL LOOKUP VARNAME exception.

How to catch that? You can catch the exception after subst has failed as usual, with catch or try. The discussion you referred to was AFAICT about catching exceptions before subst has failed, which I believe still isn't possible.

ETA:

Proof-of-concept for my "discriminating try" comment. This code has tons of potential problems but at least demonstrates basically how it could be done. In the example, the handler reacts by creating a variable that has its own name in uppercase as value.

# CAUTION: demonstration code, do not use without modification 
proc handler varName {
    upvar 1 $varName name 
    set name [string toupper $varName]
}
unset -nocomplain foo bar 
set baz xyz 
set str {$foo $bar $baz}
while true {
    try {
        subst $str 
    } on ok res {
        break 
    } trap {TCL LOOKUP VARNAME} {msg opts} {
        handler [lindex [dict get $opts -errorcode] end]
    }
}
set res
# -> FOO BAR xyz
Peter Lewerin
  • 13,140
  • 1
  • 24
  • 27
  • My bad, Peter! The first command was meant to use braces instead of quotes (question edited). – Eugeniu Rosca May 25 '15 at 17:56
  • Question solved! The normal try/catch work as expected. – Eugeniu Rosca May 25 '15 at 18:05
  • Catching exceptions before they're thrown? How does that even make sense? (Tcl's semantics are strictly operational. It does what it is told to, when it is told to do it. Sometimes that involves putting things off, but that's only ever because it has been told to do just that.) – Donal Fellows May 25 '15 at 21:05
  • @DonalFellows: if I understand the discussion correctly the idea was to intercept the lookup error before it caused subst to fail and throw the exception, not to catch the exception before it was thrown. The idea does sound dubious to me, and in any case the conclusion seems to have been that it was unfeasible. – Peter Lewerin May 25 '15 at 22:25
  • Sounds like a wildly wrong and confused idea. Sometimes we just need to tell people that. – Donal Fellows May 25 '15 at 23:21
  • @DonalFellows: I went back and looked at the discussion again. To be exact, what they wanted was an extended `subst` that enabled error interception by taking an `unknown`-style handler for missing variables as a command-line option. It was back in 2004: today a discriminating `try` would probably give them approximately that. – Peter Lewerin May 26 '15 at 04:19