My code was mainly a proof of concept. I didn't put much thought into questions like "print -v" vs "typeset -g". I was just pleasantly surprised that the whole thing was at all possible :-)
> It's a bit strange that the initialization is needed. Private variables don't hide global variables of the same name, nor prevent their assignment, but prevent their initial declaration.
This isn't exactly an effect of private, it's the previously observed
effect that there is no way to "unlocal" a parameter in the current
scope, so you have to add it to the desired scope before declaring it
local.
Private variables are supposed to have a scope that is limited to the function where they are declared. Intuitively that implies that they should have no impact on the behavior of callees. However, that's not always the case. Consider the following example:
zmodload zsh/param/private
(() { v=; () { typeset -g v=z } }; echo 1:v=$v)
(() { v=; () { print -v v z } }; echo 2:v=$v)
(() { () { typeset -g v=z } }; echo 3:v=$v)
(() { () { print -v v z } }; echo 4:v=$v)
(() { v=; local -P v=x; () { typeset -g v=z } }; echo 5:v=$v)
(() { v=; local -P v=x; () { print -v v z } }; echo 6:v=$v)
(() { local -P v=x; () { typeset -g v=z } }; echo 7:v=$v)
(() { local -P v=x; () { print -v v z } }; echo 8:v=$v)
Here is the result
1:v=z
2:v=z
3:v=z
4:v=z
5:v=z
6:v=z
7:v=
(anon): v: attempt to assign private in nested scope
Case 1 to 4 show that both "typeset -g" and "print -v" are able to set a global variable independent of whether the variable already exists (case 1-2) or not (case 3-4).
Case 5 and 6 show that "typeset -g" and "print -v" are able to set an already existing global variable even if there is a private variable with the same name in a parent scope. In these cases, the private variable is truly private and doesn't affect the behavior of the callee.
Case 7 and 8 show that the same isn't true if the global variable doesn't already exist. I find this very counterintuitive. With truly private variables, I don't see why case 7 and 8 should exhibit a different behavior than case 3 and 4.
Philippe