Prev: How to detect if event loop is running ?
Next: regexp
From: tom.rmadilo on 3 Sep 2009 15:15 On Sep 3, 11:02 am, cla...(a)lairds.us (Cameron Laird) wrote: > OR > proc foo [list [list bar $::var]] { > do_the_real_work_of_foo $bar > } Tricky! The first step is to choose a default value which will never be used in the actual application, then you test the value of the passed in value. If it is equal to the "default" value, use the global. Some of the above examples only use the value of the global at the time the proc was defined, here is an example which uses the current value of the global variable: proc ::myproc {arg1 {arg2 "I WILL NEVER USE THIS VALUE FOR ARG2"} } { if {$arg2 eq "I WILL NEVER USE THIS VALUE FOR ARG2"} { set arg2 $::arg2 } puts $arg2 } % global arg2 % set arg2 8 8 % myproc a 8 % myproc a ttt ttt Of course, this also works with not-global variables, they just have to be in the :: namespace. Problem with using global or namespaced variables is that you might change the value of these variables inside the proc, which you might not intend to do.
From: Jonathan Bromley on 3 Sep 2009 15:27 On Thu, 3 Sep 2009 12:15:59 -0700 (PDT), "tom.rmadilo" wrote: >The first step is to choose a default value which will never be used >in the actual application, then you test the value of the passed in >value. If it is equal to the "default" value, use the global. Yuck. Why do people recommend this kludgy and fragile approach, when you can do it so much more robustly by using the "args" variadic-argument list? proc myproc {arg1 args} { switch [llength $args] { 0 {set arg2 $::var} 1 {set arg2 [lindex $args 0]} default {error "bad args: should be\n myproc arg1 ?arg2?"} } .... now use $arg1 and $arg2 .... } Default arguments are good for "in-band" defaults, like the "1" default for [incr]. They are no good for procs that need to behave differently when called with different numbers of arguments. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley(a)MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
From: tom.rmadilo on 3 Sep 2009 16:55 On Sep 3, 12:27 pm, Jonathan Bromley <jonathan.brom...(a)MYCOMPANY.com> wrote: > On Thu, 3 Sep 2009 12:15:59 -0700 (PDT), "tom.rmadilo" wrote: > >The first step is to choose a default value which will never be used > >in the actual application, then you test the value of the passed in > >value. If it is equal to the "default" value, use the global. > > Yuck. > > Why do people recommend this kludgy and fragile approach, > when you can do it so much more robustly by using the > "args" variadic-argument list? > > proc myproc {arg1 args} { > switch [llength $args] { > 0 {set arg2 $::var} > 1 {set arg2 [lindex $args 0]} > default {error "bad args: should be\n myproc arg1 ?arg2?"} > } > .... now use $arg1 and $arg2 .... > } > > Default arguments are good for "in-band" defaults, like the "1" > default for [incr]. They are no good for procs that need to > behave differently when called with different numbers of arguments. args is for an unknown number of additional agruments, and if there ever was a kludge it would be using args to simulate overloaded commands/functions. The current example is already ugly. I would never recommend my solution, but I would first off, never recommend the situation which required such a solution. The "args" argument should usually be used with a high level branching command to feed into a more specific command. But it also works when all remaining arguments are members of a group (like [lappend x a b c ...]. The problem with your "args" solution is that it is more ambiguous than my hack. Both solutions require a hidden interpretation of the arguments, but the "args" solution is the most ambiguous. With "args" there are no limits on the ambiguity. IMHO, use args when you intend to expose a complex set of related commands (like [file ...], [string ...], etc.), but in this instance, I don't see any need to use args (which I agree is very useful in certain circumstances and I can provide working examples if you need 'em). Personally I never use globals, which are stupid and extremely short sighted, but some exist, and the concept exists. Just because something exists does not mean that it can be used everywhere. This is true of both global vars and args.
From: miguel sofer on 3 Sep 2009 18:39 Jeff Godfrey wrote: > How about something like... > > proc foo {{bar ""}} { > if {$bar eq ""} { > set bar $::var > } > puts $bar > } Better: proc foo {{bar ""}} { if {[llength [info level 0]] == 1} { set bar $::var } puts $bar }
From: Jonathan Bromley on 4 Sep 2009 03:51
On Thu, 3 Sep 2009 13:55:24 -0700 (PDT), "tom.rmadilo" wrote: >args is for an unknown number of additional agruments Eh? Since I can *inspect* the number of arguments passed as $args, and throw an informative error if it's inappropriate, I cannot see why you try to make that prescription. > if there ever was a kludge it would be using > args to simulate overloaded commands/functions. I just don't understand you here. What's kludgy about being able to check the number of arguments you've received, and using that value to determine how to proceed or how to error-out? >The problem with your "args" solution is that > it is more ambiguous than my hack. I completely fail to see its ambiguity. It throws an error if abused. It gives distinct behavior in the two distinct cases, much in the same way that the built-in [set] does. Apart from the fact that I didn't get around to writing a man page for it, what's ambiguous about that? >Both solutions require a hidden interpretation of the >arguments What's "hidden" about it? Every proc does "hidden" interpretation of its arguments - that's called the body of the proc :-) -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley(a)MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. |