Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

upvar and "event driven"

9 views
Skip to first unread message

Paul D.Smith

unread,
Sep 5, 2005, 8:13:01 AM9/5/05
to
OK, what's the deal? I've seen some cryptic "can't use upvar if event
driven" statements on the web but not details as to why. Anyone what to
chip in please?

Thanks,
Paul DS.

--
Please remove the "x-" if replying to sender.


miguel sofer

unread,
Sep 5, 2005, 8:53:59 AM9/5/05
to
Note that 'upvar' is typically used to refer to variables in a caller's
environment (or caller's caller, etc.).

When an event runs, the caller has long since returned - its
environment does not exist any longer, you cannot upvar to its
variables. Event callbacks run in the global namespace, at call-stack
level #0.

The exception of course is that you can do
upvar #0 a b
but this effect is clearer if you call
global a
instead - assuming the renaming of the variable is not so important.

HTH
Miguel

Arjen Markus

unread,
Sep 5, 2005, 9:01:18 AM9/5/05
to
Can you post some more details? Do you have some code that exhibits
this?
Where on the web did you see such statements?

Regards,

Arjen

Paul D.Smith

unread,
Sep 5, 2005, 9:22:30 AM9/5/05
to
"miguel sofer" <miguel...@gmail.com> wrote in message
news:1125924839.8...@g44g2000cwa.googlegroups.com...

I sort of understand this but I got the impression that upvar works back up
the call-stack. What I have is... (note this is not good TCL ;-)

proc event_function {
call f1 {x y}
}

proc f1 {x y} {
call f2 {z}
}

proc f2 {z} {
upvar z local_z
local_z = 12
}

I had expected this to work since I expected upvar to indicate the context
of f1, which I would expect to be valid. But this doesn't work and it
confused the hell out of me until I found the "notes" on the web.

Paul DS.


Paul D.Smith

unread,
Sep 5, 2005, 9:23:02 AM9/5/05
to
Google for...

upvar "event driven"

and this will lead you to the links that I was looking at.

Paul DS


miguel sofer

unread,
Sep 5, 2005, 9:57:12 AM9/5/05
to
Your expectations are correct, the general rule "you cannot use upvar
in event driven Tcl" is a wild generalisation. Your example works fine
... if you rewrite it in Tcl - here is actual proof:

mig@ave:~$ cat /tmp/test
set z 0

proc event_function {} {
f1 x y
}

proc f1 {x y} {
f2 z
puts "z is now $z"
}

proc f2 {z} {
upvar z local_z

set local_z 12
}

after 500 {
event_function
set done 1
}

vwait done

# This shows that the global was not touched
puts "global z is now $z"


mig@ave:~$ tclsh /tmp/test
z is now 12
global z is now 0

Bryan Oakley

unread,
Sep 5, 2005, 10:16:09 AM9/5/05
to
Paul D.Smith wrote:
> "miguel sofer" <miguel...@gmail.com> wrote in message
> news:1125924839.8...@g44g2000cwa.googlegroups.com...
>
>>Note that 'upvar' is typically used to refer to variables in a caller's
>>environment (or caller's caller, etc.).
>>
>>When an event runs, the caller has long since returned - its
>>environment does not exist any longer, you cannot upvar to its
>>variables. Event callbacks run in the global namespace, at call-stack
>>level #0.
>>
>>The exception of course is that you can do
>> upvar #0 a b
>>but this effect is clearer if you call
>> global a
>>instead - assuming the renaming of the variable is not so important.
>>
>>HTH
>>Miguel
>>
>
>
> I sort of understand this but I got the impression that upvar works back up
> the call-stack. What I have is... (note this is not good TCL ;-)

Indeed. It's impossible to know why your code doesn't work without
seeing the actual code. Maybe the problem is this:

> proc f2 {z} {
> upvar z local_z
> local_z = 12
> }
>

Most often, the correct upvar syntax is:

upvar $z local_z

Note the '$' preceeding z. 'z' is a local variable that contains the
name of the variable in the caller's context. It is that name (the name
of the variable in the caller's context) that you want to associate with
a local variable.

Now, in the code you posted this could have worked since the caller used
the variable 'z' too. But since this is just a hacked up "my code is
sort-of like this" example it's hard to know what the problem really is.

To more sucinctly answer your question: there is no restriction on upvar
with respect to event driven programs. The only restriction is that code
run from an event may not be running in the same context you think it is.

Bryan Oakley

unread,
Sep 5, 2005, 10:27:21 AM9/5/05
to

The first link points to the wiki. It doesn't say "upvar won't work in
event driven programs", though it does say "if the function is event
driven, you are forced to use global variables". That's not quite the
same thing. Nevertheless, I've tweaked the wiki page to clarify the point.

The only other article that catches my eye is the Tcl FAQ at
http://www.science.uva.nl/~mes/tcl/tclFAQ/QandA/tcl.html (and maybe
other places -- I haven't looked at the tcl faq in a decade or more).
The FAQ makes the same exact statement, though in the context of arrays
rather than variables in general.

None of the other references from google seem to imply any such
restriction. though I didn't look deeply at all of them. Perhaps this is
a case of one vague statement from years ago being duplicated several
times over.

Paul D.Smith

unread,
Sep 5, 2005, 11:33:24 AM9/5/05
to
Thanks,

I'll give "adding a dollar" a try when I get a few moments. I found this
bit of "web gossip" because I was finding that my attempt at upvar did not
work and I could not find anything wrong in my code (despite "sleeping on
it" overnight - my usual cure for silly error).

I'll go back and see if I can make it work in a while as I'd prefer to avoid
the global variables that I'm currently using.

Thanks to all for help and hints,
Paul DS


0 new messages