How do you provide default arguments to a Tcl procedure that are evaluated at call-time?
Here's an example of what I've tried:
> tclsh
% proc test { {def [expr 4 + 3]} } { puts $def }
too many fields in argument specifier "def [expr 4 + 3]"
% proc test { {def {[expr 4 + 3]}} } {puts $def}
% test
[expr 4 + 3]
% test 5
5
% proc test { {def {[expr 4 + 3]}} } {puts [$def]}
% test
invalid command name "[expr 4 + 3]"
% proc test { {def {[expr 4 + 3]}} } {puts [eval $def]}
% test
invalid command name "7"
The example is just to simplify code. Of course in this simple example one would just use {def 7}
to set the proc's default value.
However, the goal is to be able to call some more complex function that delivers a good default value whenever the procedure test
is being called. So the defaults can vary.
My current solution is to default to the empty string and check that:
% proc test { {def {}} } { if {$def == {}} { set def [expr 4 + 3] } ; puts $def }
% test
7
% test 5
5
However I consider this not elegant enough: There ought to be a way to put declarations where they belong: In the header.
Also, possibly, the empty string might be a perfectly fine value given by a caller that is not to be replaced with the default call.
Another workaround could be to just use args
as a parameter and then inspect that one. But that provides even less explicit declarative style.
Any ideas how I can incorporate the eval into the declarative proc header?
(I'm on Tcl8.4 with no way to upgrade because of use in a commercial tool environment. But for the sake of this site I'd also encourage answers for more modern tcl versions)