Prev: How to detect if event loop is running ?
Next: regexp
From: tom.rmadilo on 4 Sep 2009 11:08 On Sep 4, 7:31 am, Bruce <Bruce_do_not_...(a)example.com> wrote: > Uwe Klein wrote: > > Alexandre Ferrieux wrote: > >> set ::Defaults(procA) [ list -items 22 -levels 5] > >> proc procA args { > >> array set opt $::Defaults(procA) > >> array set opt $args > >> # body of proc, using $opt(-...) > >> } > > >> -Alex > > nice. > > Thinking about where the downside is. > > the one downside (and your version had it too ;) > is that is silently ignores invalid options > so if i typo an option name in the call e.g. > > procA -ietms 5 > > instead of an error, i just get the default value > and have no idea where i screwed up. This code doesn't flag an error, but it won't set the variable if it isn't named properly by the caller. Also, it removes the leading "-", which is optional: proc ::tnt::setArgs { args } { foreach arg $args { set __option [lindex $arg 0] upvar $__option $__option set $__option [lindex $arg 1] } uplevel { foreach {__option __value} $args { set __option [string trimleft $__option "-"] set $__option $__value } } } Use setArgs like this in proc: proc ::tnt::cookie::setCookie { name value args } { variable SetCookie2Version variable SendSetCookie2 ::tnt::setArgs\ {Comment ""}\ {CommentURL ""}\ {Discard "true"}\ {Domain ""}\ {Max_Age ""}\ {Path "/"}\ {Port "any"}\ {Secure "false"} ..... } Call proc like this: ::tnt::cookie::setCookie SessionID ABCD123... -Path /images -Max_Age 600 Note that you can't change the "default" value with each call, which makes no sense anyway.
From: Koyama on 5 Sep 2009 13:33 On Sep 4, 4:31 pm, Bruce <Bruce_do_not_...(a)example.com> wrote: > Uwe Klein wrote: > > Alexandre Ferrieux wrote: > >> set ::Defaults(procA) [ list -items 22 -levels 5] > >> proc procA args { > >> array set opt $::Defaults(procA) > >> array set opt $args > >> # body of proc, using $opt(-...) > >> } > > >> -Alex > > nice. > > Thinking about where the downside is. > > the one downside (and your version had it too ;) > is that is silently ignores invalid options > so if i typo an option name in the call e.g. > > procA -ietms 5 > > instead of an error, i just get the default value > and have no idea where i screwed up. > > Bruce another downside is that $opt(-item1) is slightly slower then $item1 if one sets defaults for every arg then you could check via [::llength [::array names opt]] if there is an invalid option koyama
From: Koyama on 7 Sep 2009 05:50 On Sep 4, 5:08 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > On Sep 4, 7:31 am, Bruce <Bruce_do_not_...(a)example.com> wrote: > > > > > Uwe Klein wrote: > > > Alexandre Ferrieux wrote: > > >> set ::Defaults(procA) [ list -items 22 -levels 5] > > >> proc procA args { > > >> array set opt $::Defaults(procA) > > >> array set opt $args > > >> # body of proc, using $opt(-...) > > >> } > > > >> -Alex > > > nice. > > > Thinking about where the downside is. > > > the one downside (and your version had it too ;) > > is that is silently ignores invalid options > > so if i typo an option name in the call e.g. > > > procA -ietms 5 > > > instead of an error, i just get the default value > > and have no idea where i screwed up. > > This code doesn't flag an error, but it won't set the variable if it > isn't named properly by the caller. Also, it removes the leading "-", > which is optional: > > proc ::tnt::setArgs { args } { > > foreach arg $args { > set __option [lindex $arg 0] > upvar $__option $__option > set $__option [lindex $arg 1] > } foreach arg $args { upvar [lindex $arg 0] var set var [lindex $arg 1] } orig: 71.013 microseconds per iteration faster: 57.967 microseconds per iteration slightly faster
From: tom.rmadilo on 7 Sep 2009 22:39 On Sep 7, 2:50 am, Koyama <koyam...(a)gmail.com> wrote: > On Sep 4, 5:08 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > > proc ::tnt::setArgs { args } { > > > foreach arg $args { > > set __option [lindex $arg 0] > > upvar $__option $__option > > set $__option [lindex $arg 1] > > } > foreach arg $args { > upvar [lindex $arg 0] var > set var [lindex $arg 1] > } > > orig: 71.013 microseconds per iteration > faster: 57.967 microseconds per iteration > > slightly faster I'm not impressed by the speed gains (one million requests and I save users 13 seconds), but the code is a little cleaner, so I'll update the proc. I'm more concerned with the following uplevel polluting the caller with __option and __value variables. The point of the proc is simple documentation (note that the defaults show up as part of the proc body) and removing the args handling code from the procedure. I know it is a personal preference, but I really don't like options. They usually document the desire to reuse code by making it more complicated and fragile. The basic Tcl API mostly avoids this, and all the complexity is handled in C code anyway, where there are lots of good examples of option handling. It would be ideal if options could be boiled down into subcommands. This isn't possible with every command, but I was able to reduce the new 8.5+ [switch] command into exactly 12 subcommands. If [switch] had been written this way, more opportunities would exist for compiling switch bodies.
From: Donal K. Fellows on 8 Sep 2009 06:36
On 8 Sep, 03:39, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote: > I'm not impressed by the speed gains (one million requests and I save > users 13 seconds), but the code is a little cleaner, so I'll update > the proc. 18% is quite a good improvement, FWIW, especially as it is really not much more than a peephole optimization. Small scale stuff usually only wins a percent or so... Donal. |