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