0

I want to return from a configbody but cannot do so explicitly without causing the variable not to be set.

I'd like help understanding the behavior I'm seeing. Please consider the following code (using Itcl 3.4):

package require Itcl
catch {itcl::delete class Model}
itcl::class Model {
    public variable filename "orig"
}

itcl::configbody Model::filename {
    if 1 {
        return ""
    } else {
    }
}

Model my_model
my_model configure -filename "newbie"
puts "I expect the result to be 'newbie:' [my_model cget -filename]"

When I return empty string, filename is not set to the new value. If I do not return but just allow the proc to fall through, filename does change. You can see this by changing the 1 to a 0 in the above code.

I suspect its related to the following statement:

When there is no return in a script, its value is the value of the last command evaluated in the script.

If someone would explain this behavior and how I should be returning, I'd appreciate the help.

Robert Lugg
  • 1,090
  • 2
  • 12
  • 40

1 Answers1

1

Tcl handles return by throwing an exception (of type TCL_RETURN). Normally, the outer part of a procedure or method handler intercepts that exception and converts it into a normal result of the procedure/method, but you can intercept things with catch and see beneath the covers a bit.

However, configbody does not use that mechanism. It just runs the script in some context (not sure what!) and that context treats TCL_RETURN as an indication to fail the update.

Workaround:

itcl::configbody Model::filename {
    catch {
        if 1 {
            return ""
        } else {
        }
    } msg; set msg
    # Yes, that's the single argument form of [set], which READS the variable...
}

Or call a real method in the configbody, passing in any information that's required.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215