-m is not supposed to work at all with named references.
Right, you can't combine -m and -n but you can use -m alone or with -p to print existing parameters. This currently misbehaves in the presence of named references.
> In ksh, any attempt to dereference a placeholder reference triggers an error. Zsh should do the same.
I disagree (except in ksh emulation mode).
So should there be a check for ksh emulation mode? Currently I'm not aware of any such check in the code for named references but this would definitely need one if we aim to behave like ksh in emulation mode.
There are other parameter
cases where ksh has errors but zsh has traditionally yielded empty
string.
About a week ago I wrote a test to check all the different kinds of expansions (${P}, ${+P}, ${P-…}, ${P+…}, …) for all kinds of references, including placeholder references. A little to my surprise, it all looked good. This wasn't the case last year but it looks like the many patches fixed all the issues. Iirc, placeholder references behaved as if they were references to an empty string parameter. In ksh, any expansion of a placeholder reference triggers an error but I agree that the current Zsh behavior is a viable alternative. However, if that's what we want but also want a faithful ksh emulation mode, then some extra logic is needed to raise errors in ksh emulation mode.
> Currently it sometimes exhibits rather dubious behaviors in place of triggering an error.
However, I agree that anything other than behaving like
${an_unset_scalar} would be dubious.
One example of dubious behavior is if you try to unset (with no -n) a placeholder reference or a chain to a placeholder reference. This should unset the referred variable but since there is no such variable the current code unsets the placeholder reference. I think that in this case it would make more sense to complain about the fact that there is no referred variable. Similarly, if you use typeset -i var to change the type of var and it turns out that var refers to a placeholder reference, it tries to change the type of the placeholder reference (which triggers an incompatible type change error) while it would make more sense to complain that there is no referred variable.
> I disagree (except in ksh emulation mode). There are other parameter
> cases where ksh has errors but zsh has traditionally yielded empty
> string.
This sounds a little bit like NO_UNSET?
A placeholder reference is a reference that doesn't yet refer to any variable but a reference can also refer to a variable that isn't yet defined. It's two different kinds/levels of undefinedness. To me the former looks way more severe than the latter. However because it's such a different kind/level, it's not clear to me whether NO_UNSET should be involved at all in the former. Currently it only impacts references to not-yet-defined variables:
% set -u; typeset -n r1 r2=v2; echo r1=$r1; echo r2=$r2
r1=
zsh:1: r2: parameter not set
Since r1 is defined but just happens to not yet refer to any variable, it's not necessarily wrong for NO_UNSET to not complain. However, the following is a little disturbing:
% set -u; typeset -n r1; echo r1=$r1; r1=v1; echo r1=$r1
r1=
zsh:1: r1: parameter not set
It's a bit weird that assigning a value to r1 turns it from defined to undefined.
In ksh this weirdness is avoided by triggering an error as soon as one tries to dereference a placeholder reference. If in Zsh we allow expansions of placeholder references, then it might be unavoidable that a few scenarios exhibit some weirdness. Should NO_UNSET complain about placeholder references? At least in the examples above, results would look more consistent.
Philippe