From: tom.rmadilo on
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
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
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
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
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.
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5
Prev: How to detect if event loop is running ?
Next: regexp