zsh-workers
 help / color / mirror / code / Atom feed
From: Stephane Chazelas <stephane@chazelas.org>
To: Bart Schaefer <schaefer@brasslantern.com>
Cc: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: [PATCH] Fix crash on unset-through-nameref
Date: Tue, 5 Mar 2024 08:18:59 +0000	[thread overview]
Message-ID: <20240305081859.r3qwiyduk2wgkdby@chazelas.org> (raw)
In-Reply-To: <CAH+w=7ZiTe_hPoBRtHBsRHRvifkiaCJPOCzRSpz0H=XHV8rNbw@mail.gmail.com>

2024-03-04 15:18:06 -0800, Bart Schaefer:
> On Mon, Mar 4, 2024 at 11:34 AM Stephane Chazelas <stephane@chazelas.org> wrote:
> >
> > 2024-03-04 00:39:30 -0800, Bart Schaefer:
> > >
> > > Try removing this line from the patch:
> > >
> > > +    pm->node.flags |= PM_DECLARED;
> >
> > $ ./Src/zsh -c 'myunset() { typeset -n v=$1; unset v; }; export x=1; myunset x; typeset -p x; x=2; typeset -p x'
> > export x=2
> >
> > It still retained its export attribute.
> 
> This gets messy because POSIX says that's exactly what's supposed to
> happen when unsetting an export, even though in native zsh it normally
> doesn't work that way.

No, I think you're confusing with:

export foo

Which is meant to give the export attribute to foo without
giving it a value (so the variable will end up in the
environment of executed command if ever its assigned in the
future but not until then).

unset foo (or better unset -v foo as POSIX allows bash's
behaviour where that could unset a function instead) is required
to clear the value and export attribute.

unset is the only way to unexport a variable in POSIX shells.


> You'll note it also didn't say
>   typeset: no such variable: x
> 
> ... because there is no provision in the parameter implementation for
> a global to occupy a table slot and yet to appear not to exist.
> 
> This is one of the reasons your desire for "create it an as unset at
> the time a nameref mentions it" has inherent problems.

I was suggesting a "unset (and undeclared then) but named ref"
(and refcount if needed for garbage collection) flag for that in
a separate message, but I have no idea whether that'd be
sufficient or feasible.

I hate to say this but it seems to me that if this kind of issue
is not fixable, then it would likely be preferable (from a
consistency PoV at least) to go for bash/mksh dumber approaches
where namerefs are just plain scalar variables containing the
name of another variable (or other lvalue) and having the target
variable resolved any time the nameref is assigned/referenced
(in whatever scope that happens to be).

You'd still need to namespace your variables in functions using
namerefs, even more so, but at least it would be more consistent
and we wouldn't have to list all the special cases that work or
don't work in the documentation

BTW, speaking of "other lvalue", see also:

$ ksh -c 'typeset -n a="b[n++]"; typeset -p n; b=(); a=a a=b a=c; typeset -p b n'
n=2
typeset -a b=([1]=c)
n=2
$ mksh -c 'typeset -n a="b[n++]"; typeset -p n; b=(); a=a a=b a=c; typeset -p b n'
set -A b
typeset b[0]=a
typeset b[2]=b
typeset b[4]=c
typeset n=6
$ bash -c 'typeset -n a="b[n++]"; typeset -p n; b=(); a=a a=b a=c; typeset -p b n'
bash: line 1: typeset: n: not found
declare -a b=([0]="a" [1]="b" [2]="c")
declare -- n="3"
$ ./Src/zsh -c 'typeset -n a="b[n++]"; typeset -p n; b=(); a=a a=b a=c; typeset -p b n'
zsh:typeset:1: no such variable: n
typeset -a b=( a '' b '' c )
typeset -i n=6

Which suggests the lvalue is still evaluated by zsh at every assignment at
least.

(see also
https://unix.stackexchange.com/questions/640687/prevent-command-substitution-from-running-when-declaring-a-variable/640695#640695
where namerefs are abused to have a variable with a dynamic
value).

-- 
Stephane


  reply	other threads:[~2024-03-05  8:19 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-04  5:37 Bart Schaefer
2024-03-04  6:29 ` Stephane Chazelas
2024-03-04  8:39   ` Bart Schaefer
2024-03-04 19:34     ` Stephane Chazelas
2024-03-04 19:36       ` Stephane Chazelas
2024-03-04 23:50         ` Bart Schaefer
2024-03-05  8:36           ` Stephane Chazelas
2024-03-04 23:18       ` Bart Schaefer
2024-03-05  8:18         ` Stephane Chazelas [this message]
2024-03-05 18:42           ` Bart Schaefer
2024-03-05 19:38             ` Stephane Chazelas
2024-03-05 23:16               ` Bart Schaefer
2024-03-06 18:21                 ` Stephane Chazelas
2024-03-06 19:17                   ` Bart Schaefer
2024-03-06 19:37                     ` Bart Schaefer
2024-03-05 19:48             ` unset, POSIX and the export attribute (Was: [PATCH] Fix crash on unset-through-nameref) Stephane Chazelas
2024-03-05 19:51             ` [PATCH] Fix crash on unset-through-nameref 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=20240305081859.r3qwiyduk2wgkdby@chazelas.org \
    --to=stephane@chazelas.org \
    --cc=schaefer@brasslantern.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).