2021年4月6日(火) 21:06 Greg Wooledge <g...@wooledge.org>: > On Tue, Apr 06, 2021 at 02:55:35PM +0900, Koichi Murase wrote: > > But, maybe we can introduce a special syntactic treatment of `unset' > > When I made a comment about the possibility of unset becoming a keyword, > Chet said he had no plans to do that. > > ... here: > https://lists.gnu.org/archive/html/bug-bash/2021-03/msg00236.html
Thank you for the pointer. I still think changing the syntactic treatment of the arguments of the `unset' builtin is the cleanest way to solve the problem of `key=@; unset -v a[$key]'. Maybe we can ask Chet why this isn't considered. We now see two benefits of changing the treatment of the arguments of `unset', 1) `unset -v a[$key]' is not the subject to the pathname expansions and word splitting. 2) we can distinguish the erasure of the element associated with key=@ `unset -v a[$key]' from the entire array erasure `unset -v a[@]'. (But maybe there is a technical difficulty in introducing the new syntaxes.) To implement this, `unset' doesn't need to be turned into a shell keyword, but I thought just the treatment of arguments might be changed. For a similar example, the assignments in the declare arguments `declare a[$key]=$value' is treated specially although `declare' is not a shell keyword but a builtin. In the follow-ups, rle has pointed out that `unset' would be no longer overridable by functions if it was turned into a keyword. But, if we just change the treatment of the arguments of the form `name[key]', we don't have to break the backward compatibility. For the backward compatibility, we can keep the treatment of the quoted arguments like 'a[$key]' but just change the form `name[key]' which is currently unsafe against the pathname expansions. There may be some use cases broken by this change, but they would be something highly unusual like the following: $ key='1] b[2' $ unset -v a[$key] # intended to remove `a[1]' and `b[2]' or $ touch a1 a2 a3 $ unset -v a[1-3] # intended to remove `a1', `a2', and `a3' I don't think there are existing codes relying on these behaviors. Conversely, there are definitely more codes naively writing as `unset a[1]' which can be broken by pathname expansions. For this reason, I think we don't have to care about the backward compatibility for this change, but rather we can expect that the compatibility would be improved. -- Koichi