I was under the assumption - don’t remember where I picked this up - that the upvar in Snap! works the same way as in TCL - meaning that you “name” a var that exists on a higher level.
After doing so, the value of the var that has been named can be read AND changed.
After the routine with the upvar ends, the named var has been changed.
Apparently not so in Snap! ?? According to what I tested, the upvar can only be set inside the subroutine and than be read on a higher level.
See my test here:
The first time I “say” the value of A (as an upvar) inside testupVars it has no value.
After changing the upvar A inside it indeed appears to be changed (last say command)
For me, It first is “toplevel”, then it is “A”, then “upvar”, and it stays “upvar”, although the variable display doesn’t change on stage, and if I click the variable to manually get the value, it stays as “toplevel”.
The issue isn’t about reading vs. writing. It’s about scope of variables.
An upvar actually has two scopes, because it has two bindings, which is why you can change the upvar’s name in the calling script by clicking on the upvar symbol. There is a binding of the upvar’s original name inside the procedure where it’s declared (testUpVars in your example (you can put spaces in variable names in Snap!; no need for hideous camelCase :~) )), whose scope is that entire procedure definition. And there’s a binding in the caller of that procedure (namely your toplevel script) of the possibly-renamed upvar; its scope is from the call of testUpVars to the end of the script.
If it didn’t work that way, in your example you wouldn’t be able to use the upvar in the calling script at all!
(Side comment: Upvars are commonly used in C-shaped blocks; the canonical example is FOR. In that situation one could argue that the scope of the outer binding should be only the script inside the C-slot. But Jens adamantly rejects such arguments.)
The global binding of that variable name (note that “toplevel” is different from “global” because there are toplevel scripts, as in your example) is indeed not changed when the value of the upvar is changed.
(Another side comment: Decades ago, our programming language friends yelled at me for saying in Computer Science Logo Style that a variable is a binding of a name to a value; officially, a variable is an association of a location (a memory address; think of it as a box) and a value, and the binding of a name to a variable (not to a value) is external to the variable, in an environment. But I never understood why it mattered until we invented upvars in Snap!. An upvar is one variable with two names (one box, two bindings).)