But that's exactly what's not supposed to happen. "typeset -nu"
references are allowed to create globals, "typeset -n" references are
not (they can only update what already exists).
?!? Since when is that the case? The current HEAD and the test release both create global variables when assigning to a reference that refers a not-yet-defined variable:
function () {
typeset -n ref=var
ref=foo
typeset -p ref var
}
typeset -p var
Output:
typeset -n ref=var
typeset -g var=foo
typeset var=foo
There is no explicit documentation of that case but the following statement from section 14.3.2 strongly suggests that for non-upper references assignment to not-yet-defined should work.
To force a named reference to refer to the outer scope, even if a local has already been declared, add the -u option when declaring the named reference. In this case rname should already exist in the outer scope, otherwise the behavior of assignment through pname is not defined and may change the scope of the reference or fail with a status of 1.
I have no clue what is meant with "and may change the scope of the reference". Does that mean that the variable should be created in the local scope? If yes, which one? The current one, the one where the reference was initialized, or the one in which the reference was defined? In any case, the current implementation seems to always create the variable in the global scope (which is also what ksh does).
There is also this statement in the same section, which again strongly suggests that for non-subscripted references a variable should be created.
Unlike ‘(P)’, named references in substitutions that perform assignment, such as ${pname::=word}, do not create new arrays when rname is in the form of an array element or slice and no such array (or associative array) is presently set.
If non-upper references are not supposed to create variables then I have to ask why. Why should there be such a difference between -n and -nu references? I don't see anything in the documentation that points to such a difference, quite on the contrary (see above).
No. The "title" of that test is "local nameref may not in-scope a
global parameter" -- a "typeset -n" reference can only refer to an
object that is either already in scope, or that later comes into the
namref's local scope by other means.
Here again, I have to admit that I have no clue of what is meant with "may not in-scope a global parameter" but I have a hard time to equate this to "references can't create (global) variables".
This should not happen, because unless the previous function has gone
wrong, there is no global zz variable. The second function is there
to check that the first one did NOT create a global parameter.
A simple "typeset -p zz" at the top-level would be an easier way to check that there is no global "zz". As suggested by the comment below the test title ("previously this could create an infinite recursion and crash"), I suspect that the test is there for some other reason than (just) testing the creation of global variables.
Regarding your 5 examples, I agree with all of them, but none of them address the case present in the two examples related to the current bug.
More importantly, even if it were true that non-upper references are not supposed to create variables (or global variables), it wouldn't change the fact that the "upscope" under discussion is bogus. In my original example, it doesn't prevent the creation of a global variable. It only causes the creation of the wrong global variable, namely "var1" instead of "var2".
Philippe