Re: [TCLCORE] Variable access (was Re: [Tcl9-cloverfield], Parser)
by Twylite other posts by this author
May 9 2008 5:58AM messages near this date
Re: [TCLCORE] Variable access (was Re: [Tcl9-cloverfield], Parser)
|
Re: [TCLCORE] Variable access (was Re: [Tcl9-cloverfield], Parser)
Hi,
> How can $&foo syntax guarantee that a variable named foo exists any
> more than upvar can?
Upvar can't. Upvar links to the variable irrespective of whether it
exists or not. If you try to dereference the local name and the given
variable doesn't exist in the caller's scope then you get an error.
> Right -- so the only difference is a slightly improved error message?
Yes :)
Well, no. Errors are handled in the right context, and the error is
thrown for the right context and with the right name. And your proc can
treat the variable as a (local) parameter, while the caller gets to
determine if it should be passed by value or as a reference (in which
case changes made by the proc are available to the caller).
Upvar means that errors are discovered in the proc when you dereference
the linked variable. The programming error was when you passed in the
wrong variable name. The error message you get (with upvar) is
misleading because it indicated the linked variable name in the proc,
not the name of the linked-to variable (which is in a different scope).
Here's an even closer implementation:
(You can't actually implement $& in Tcl. My proc assumes that any value
starting with & is intended as a reference - this isn't quite good enough)
proc add5 {var} {
# ----- With $& syntax this bit would be implicit -----
if { [string match "&*" $var] } {
# we're looking at a reference not a value, so attempt to resolve it
set var [string range $var 1 end]
if { [uplevel 1 [list info vars $var]] eq {} } {
return -code 1 -level 1 "can't read \"$var\": no such variable"
}
upvar 1 $var [unset var]var
}
# -----
puts [incr var 5]
}
set a 10
add5 5 -> 10
add5 a -> expected integer but got "a"
add5 $a -> 15
add5 $a -> 15
add5 &a -> 15
add5 &a -> 20
puts $a -> 20
> > To added advantage to $& over upvar is that the caller can select to
> > call by reference _or_ by value (discarding potential output from the
> > proc).
>
> Is that really an interesting thing to do though? It would just seem
> to lead to confusion, e.g.:
>
> proc add10 var { incr var 10 }
> set foo 1
> add10 $foo ;# does nothing at all - no error
>
> With [upvar] you at least get an error in this situation.
>
The example you have given is a function (no side-effects). I have
encountered situations when I have had to duplicate a variable before
calling a proc that takes a varname, because I needed the original value
and the return value of the proc, but not necessarily the changed var
value. I'm struggling to think of a good example right now but this may
suffice:
set b alpha -> alpha
set c [lappend b beta] -> alpha beta
puts $b -> alpha beta
puts $c -> alpha beta
What if I need "alpha" and "alpha beta", i.e. the original $b and the
final $c?
But if lappend had been written to use references:
set b alpha -> alpha
set c [lappend $&b beta] -> alpha beta
puts $b -> alpha
puts $c -> alpha beta
Regards,
Trevor
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Tcl-Core mailing list
Tcl-Core@[...].net
https://lists.sourceforge.net/lists/listinfo/tcl-core
Thread:
Twylite
Larry McVoy
Rna020
Neil Madden
Twylite
Neil Madden
Twylite
Neil Madden
|