zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Peter Stephenson <p.w.stephenson@ntlworld.com>,
	Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: [PATCH (not final)] (take three?) unset "array[$anything]"
Date: Thu, 3 Jun 2021 11:12:19 -0700	[thread overview]
Message-ID: <CAH+w=7bjefwczt_YaUFK+aGno4G6mJKjnozgj280KBdBH94awA@mail.gmail.com> (raw)
In-Reply-To: <20210603131347.i7bv7ao7j3hk3a2e@chazelas.org>

[-- Attachment #1: Type: text/plain, Size: 3153 bytes --]

On Thu, Jun 3, 2021 at 6:14 AM Stephane Chazelas <stephane@chazelas.org> wrote:
>
> If I understand correctly, the "stripquote" variant is the one
> where the user can do:
>
> unset 'hash["foo"]'
>
> unset "hash['']"
>
> unset "hash[${(qq)key}]"
>
> That is where quotes are parsed and removed but otherwise
> serve no purpose.

I guess you can describe it that way, yes.

> That hardly helps with backward compatibility as users who did
> work around the previous behaviour will still have to adapt
> their work around

The point of my previous analysis is that they probably will not have
to adapt.  Your $MATCH workaround operates correctly with the
stripquote version in nearly as many cases as it currently does (it is
not foolproof for the current shell implementation).

However, that doesn't mean I advocate for this over the "literal" variant.

> and those who didn't (who did unset
> "hash[$key]") will have their code choke on even more characters
> (", $, ' in addition to the previous ones, and likely more
> confusing behaviour when there are unmatched quotes or ()).

I extended my test set to include a number of variations on those
characters as well.  I've attached the test script.

Here are my test cases that fail if you just blindly do
  for k in ${(k)ax}; do unset "ax[$k]"; done
  typeset -p ax
with appropriate trapping for the fatal errors.  The literal variant
gets all of these, leaving the test hash empty.  Neither literal nor
stripquote throws any errors, so the trap is only needed for the
current implementation.  Starting with that:

typeset -A ax=(
  [$'\M-\C-@\\']=$'\M-\C-@\\'
  [$'\M-\C-@`']=$'\M-\C-@`'
  ['"${(@w)oops"']='"${(@w)oops"'
  ['(a']='(a'
  ['\$']='\$'
  ['\(']='\('
  ['\)']='\)'
  ['\[']='\['
  ['\\\']='\\\'
  ['\\\\']='\\\\'
  ['\]']='\]'
  ['\`']='\`'
)

The cases that fail with the stripquote variation:

typeset -A ax=(
  [$'\M-\C-@\\']=$'\M-\C-@\\'
  ['""']='""'
  ['"$oops"']='"$oops"'
  ['"safe"']='"safe"'
  ['"set"']='"set"'
  [\'\']=\'\'
  [\''safe'\']=\''safe'\'
  [\''set'\']=\''set'\'
  ['\!']='\!'
  ['\$']='\$'
  ['\(']='\('
  ['\)']='\)'
  ['\*']='\*'
  ['\=']='\='
  ['\@']='\@'
  ['\[']='\['
  ['\\\']='\\\'
  ['\\\\']='\\\\'
  ['\]']='\]'
  ['\`']='\`'
  ['\s\a\f\e']='\s\a\f\e'
  ['\s\e\t']='\s\e\t'
)

Current shell using $MATCH workaround:

typeset -A ax=(
  [$'\M-\C-@`']=$'\M-\C-@`'
  ['"${(@w)oops"']='"${(@w)oops"'
  ['(']='('
  ['(a']='(a'
  [')']=')'
  ['[']='['
  ['\(']='\('
  ['\)']='\)'
  ['\[']='\['
  ['\`']='\`'
  ['`']='`'
)

And stripquote with $MATCH workaround:

typeset -A ax=(
  ['""']='""'
  ['"$oops"']='"$oops"'
  ['"safe"']='"safe"'
  ['"set"']='"set"'
  [\'\']=\'\'
  [\''safe'\']=\''safe'\'
  [\''set'\']=\''set'\'
  ['\`']='\`'
)

Finally, literal with $MATCH workaround:

typeset -A ax=(
  [$'\M-\C-@\\']=$'\M-\C-@\\'
  ['\']='\'
  ['\!']='\!'
  ['\$']='\$'
  ['\(']='\('
  ['\)']='\)'
  ['\*']='\*'
  ['\=']='\='
  ['\@']='\@'
  ['\[']='\['
  ['\\\']='\\\'
  ['\`']='\`'
  ['\s\a\f\e']='\s\a\f\e'
  ['\s\e\t']='\s\e\t'
  [']']=']'
)

I agree that the literal variation is probably the one most useful to
re-apply in cases like read, print -v, etc.

[-- Attachment #2: test_unset.zsh --]
[-- Type: application/octet-stream, Size: 2033 bytes --]

exec 2>&1	# to see fatal error messages in proper sequence
unset ax bx oops
oops='this is a problem'
typeset -A ax bx
typeset -a kx=(
  '' '\' '`' '(' '[' ')' ']' '=' '"' "'" '!' '@' '$' '*'
  $'\0' '\\' '\`' '\(' '\[' '\)' '\]' '\=' '\!' '\@' '\$' '\*'
  '()safe' '(r)set' '(R)set' '(k)safe'	# look like valid subscript flags
  '(a' '(a)' '(n:foo:)a' '(n:1)a'	# look like invalid subscript flags
  'set' '"set"' \'set\' '\s\e\t'
  'safe' '"safe"' \'safe\' '\s\a\f\e'
  '\\' '\\\' '\\\\' '""' \'\'
  'two words' 'two  spaces' ' initial space' 'trailing space '
  $'\x80\\' $'\x80\`' $'\x80\~'		# broken UTF-8
  '?~>#'
  '$oops' '${oops}' '"$oops"' '"${(@w)oops"' '${(qqq)oops}' '$(echo oops)'
)
for ((i=0; i<255; i++)); do
  printf -v n '\\x%02x' $i
  eval "kx+=(\$'$n')"
done

for k in "$kx[@]"; do
  ax[$k]=$k
  bx[$k]=$k
done
typeset -p 1 ax
print COUNT: $#ax

print $'\nWith (b)'
for k in "$kx[@]"; do
  ( unset "ax[${(b)k}]" ) && unset "ax[${(b)k}]" &&
  print -r -- ${ax[$k]+Missed} ${(V)ax[$k]-Got $k}
done
typeset -p 1 ax

ax=(${(kv)bx})
print $'\nWith (q)'
for k in "$kx[@]"; do
  ( unset "ax[${(q)k}]" ) && unset "ax[${(q)k}]" &&
  print -r -- ${ax[$k]+Missed} ${(V)ax[$k]-Got $k}
done
typeset -p 1 ax

ax=(${(kv)bx})
print $'\nWith (qq)'
for k in "$kx[@]"; do
  ( unset "ax[${(qq)k}]" ) && unset "ax[${(qq)k}]" &&
  print -r -- ${ax[$k]+Missed} ${(V)ax[$k]-Got $k}
done
typeset -p 1 ax

ax=(${(kv)bx})
print $'\nWith (qqq)'
for k in "$kx[@]"; do
  ( unset "ax[${(qqq)k}]" ) && unset "ax[${(qqq)k}]" &&
  print -r -- ${ax[$k]+Missed} ${(V)ax[$k]-Got $k}
done
typeset -p 1 ax

ax=(${(kv)bx})
print $'\nWithout backslashes'
for k in "$kx[@]"; do
  ( unset "ax[$k]" ) && unset "ax[$k]" &&
  print -r -- ${ax[$k]+Missed} ${(V)ax[$k]-Got $k}
done
typeset -p 1 ax

ax=(${(kv)bx})
print $'\nWith pattern from workers/43269'
for k in "$kx[@]"; do
  ( unset "ax[${(*)k//(#m)[]\\]/\\$MATCH}]" ) &&
  unset "ax[${(*)k//(#m)[]\\]/\\$MATCH}]" &&
  print -r -- ${ax[$k]+Missed} ${(V)ax[$k]-Got $k}
done
typeset -p 1 ax
print COUNT: $#ax

  parent reply	other threads:[~2021-06-03 18:13 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-16 21:10 regexp-replace and ^, word boundary or look-behind operators Stephane Chazelas
2019-12-16 21:27 ` Stephane Chazelas
2019-12-17  7:38   ` Stephane Chazelas
2019-12-17 11:11     ` [PATCH] " Stephane Chazelas
2019-12-18  0:22       ` Daniel Shahaf
2019-12-18  8:31         ` Stephane Chazelas
2020-01-01 14:03         ` [PATCH v2] " Stephane Chazelas
2021-04-30  6:11           ` Stephane Chazelas
2021-04-30 23:13             ` Bart Schaefer
2021-05-05 11:45               ` [PATCH v3] regexp-replace and ^, word boundary or look-behind operators (and more) Stephane Chazelas
2021-05-31  0:58                 ` Lawrence Velázquez
2021-05-31 18:18                 ` Bart Schaefer
2021-05-31 21:37                   ` [PATCH] (?) typeset array[position=index]=value Bart Schaefer
2021-06-01  5:32                     ` Stephane Chazelas
2021-06-01 16:05                       ` Bart Schaefer
2021-06-02  2:51                         ` [PATCH] (take two?) typeset array[position=index]=value / unset hash[$stuff] Bart Schaefer
2021-06-02 10:06                           ` Stephane Chazelas
2021-06-02 14:52                             ` Bart Schaefer
2021-06-02 16:02                               ` Stephane Chazelas
2021-06-02  9:11                         ` [PATCH] (?) typeset array[position=index]=value Stephane Chazelas
2021-06-02 13:34                           ` Daniel Shahaf
2021-06-02 14:20                             ` Stephane Chazelas
2021-06-02 15:59                               ` Bart Schaefer
2021-06-03  2:04                                 ` [PATCH (not final)] (take three?) unset "array[$anything]" Bart Schaefer
2021-06-03  2:42                                   ` Bart Schaefer
2021-06-03  6:12                                     ` Bart Schaefer
2021-06-03  8:54                                       ` Peter Stephenson
2021-06-03 13:13                                         ` Stephane Chazelas
2021-06-03 14:41                                           ` Peter Stephenson
2021-06-04 19:25                                             ` Bart Schaefer
2021-06-05 18:18                                               ` Peter Stephenson
2021-06-09 23:31                                                 ` Bart Schaefer
2021-06-13 16:51                                                   ` Peter Stephenson
2021-06-13 18:04                                                     ` Bart Schaefer
2021-06-13 19:48                                                       ` Peter Stephenson
2021-06-13 21:44                                                         ` Bart Schaefer
2021-06-14  7:19                                                           ` Stephane Chazelas
2021-06-03 18:12                                           ` Bart Schaefer [this message]
2021-06-04  8:02                                             ` Stephane Chazelas
2021-06-04 18:36                                               ` Bart Schaefer
2021-06-04 20:21                                                 ` Stephane Chazelas
2021-06-05  0:20                                                   ` Bart Schaefer
2021-06-05 17:05                                                     ` Stephane Chazelas
2021-06-10  0:14                                                       ` Square brackets in command position Bart Schaefer
2021-06-03  6:05                                   ` [PATCH (not final)] (take three?) unset "array[$anything]" Stephane Chazelas
2021-06-03  6:43                                     ` Bart Schaefer
2021-06-03  7:31                                       ` Stephane Chazelas
2021-06-10  0:21                         ` [PATCH] (?) typeset array[position=index]=value Bart Schaefer
2021-06-05  4:29                     ` Mikael Magnusson
2021-06-05  5:49                       ` Bart Schaefer
2021-06-05 11:06                         ` Mikael Magnusson
2021-06-05 16:22                           ` Bart Schaefer
2021-06-18 10:53                         ` Mikael Magnusson
2024-03-08 15:30                 ` [PATCH v3] regexp-replace and ^, word boundary or look-behind operators (and more) Stephane Chazelas
2024-03-09  8:41                   ` [PATCH v5] " Stephane Chazelas
2024-03-09  9:21                     ` MBEGIN when =~ finds bytes inside characters (Was: [PATCH v5] regexp-replace and ^, word boundary or look-behind operators (and more).) Stephane Chazelas
2024-03-09 13:03                   ` [PATCH v3] regexp-replace and ^, word boundary or look-behind operators (and more) Stephane Chazelas
2024-03-10 19:52                     ` [PATCH v6] " Stephane Chazelas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAH+w=7bjefwczt_YaUFK+aGno4G6mJKjnozgj280KBdBH94awA@mail.gmail.com' \
    --to=schaefer@brasslantern.com \
    --cc=p.w.stephenson@ntlworld.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).