On Tue, Jun 1, 2021 at 9:05 AM Bart Schaefer wrote: > > [...] I should at least examine whether getasg() ought to be using > parse_subscript() even though the corresponding parse.c block is using > skipparens(). I've decided parse_subscript() is appropriate there, so that's included below. If anyone sees any problem with that, please point it out. > Whereas most subscript flags are meaningless for unset, we might > consider supporting (e) there. I'm not sure whether that would fully > address the problem with the other characters, though. Turns out it does seem to fix that, so that's the direction I've gone. More discussion below. > The issue with the empty key seems merely to be that the subscript > validity test for associative arrays never changed from the one for > plain arrays. To maintain error-equivalent backward compatibility I didn't "fix" this, instead, hash[(e)] (or hash[(e)''] if you think that more readable) is required in order to unset the element with the empty key. > [...] I'm not sure what backward-compatibility would be broken? Do you > mean that scripts that already have work-arounds for the current issue > might stop working? The one compatibility issue with the foregoing is this: Current pre-patch zsh: % typeset -A zz % bad='(e)bang' % zz[$bad]=x t% typeset -p zz typeset -A zz=( ['(e)bang']=x ) % unset zz\["$bad"\] % typeset -p zz typeset -A zz=( ) With the patch, the "(e)" appearing in the value of $bad becomes a subscript flag, because $bad is expanded before "unset" parses: % zz[$bad]=x % typeset -p zz typeset -A zz=( ['(e)bang']=x ) % unset zz\["$bad"\] % typeset -p zz typeset -A zz=( ['(e)bang']=x ) You have to double the flag: % unset zz\["(e)$bad"\] % typeset -p zz typeset -A zz=( ) Is that a small enough incompatibility for this to be acceptable? I've included doc updates, but not tests. If anyone else would like to take a stab at those?