From: Bart Schaefer <schaefer@brasslantern.com>
To: Joshua Krusell <js.shirin@gmail.com>
Cc: zsh-users@zsh.org
Subject: Re: unset private variables
Date: Sun, 3 Sep 2023 11:02:58 -0700 [thread overview]
Message-ID: <CAH+w=7a-7eDoRuO+d55g_b=9PMcHoMWpOX6RkoWPMf-g+O74HQ@mail.gmail.com> (raw)
In-Reply-To: <CAOCbtnswt_UYR8psp2sMDT=AYZOVJxmdq92P3jBP=dFghaQmLg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 362 bytes --]
On Sun, Sep 3, 2023 at 5:06 AM jsks <js.shirin@gmail.com> wrote:
>
> Unsetting a variable declared with param/private and then modifying it returns the error "can't change parameter attribute".
This is a bug, an unintended interaction with with changes introduced
for the TYPESET_TO_UNSET option (but not affected by whether that
option is in effect).
[-- Attachment #2: unset-private.txt --]
[-- Type: text/plain, Size: 3079 bytes --]
diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c
index e43f0edb4..8e04b2b95 100644
--- a/Src/Modules/param_private.c
+++ b/Src/Modules/param_private.c
@@ -230,7 +230,9 @@ setfn_error(Param pm)
* calling the original unsetfn. This assures that if the old unsetfn
* wants to use its getfn or setfn, they're unconditionally present.
* The "explicit" flag indicates that "unset" was called, if zero the
- * parameter is going out of scope (see params.c).
+ * parameter is going out of scope (see params.c). PM_DECLARED is
+ * asserted as if TYPESET_TO_UNSET were in use so that the private
+ * parameter is re-used rather than re-created when assigned again.
*
*/
@@ -268,9 +270,10 @@ pps_unsetfn(Param pm, int explicit)
pm->gsu.s = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.s = (GsuScalar)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -307,9 +310,10 @@ ppi_unsetfn(Param pm, int explicit)
pm->gsu.i = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.i = (GsuInteger)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -346,9 +350,10 @@ ppf_unsetfn(Param pm, int explicit)
pm->gsu.f = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.f = (GsuFloat)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -386,9 +391,10 @@ ppa_unsetfn(Param pm, int explicit)
pm->gsu.a = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.a = (GsuArray)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
@@ -427,9 +433,10 @@ pph_unsetfn(Param pm, int explicit)
pm->gsu.h = gsu;
if (locallevel <= pm->level)
gsu->unsetfn(pm, explicit);
- if (explicit)
+ if (explicit) {
+ pm->node.flags |= PM_DECLARED;
pm->gsu.h = (GsuHash)c;
- else
+ } else
zfree(c, sizeof(struct gsu_closure));
}
diff --git a/Src/builtin.c b/Src/builtin.c
index 31af66c7c..01df7d73b 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2697,7 +2697,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
off |= bit;
}
if (OPT_MINUS(ops,'n')) {
- if ((on|off) & ~PM_READONLY) {
+ if ((on|off) & ~(PM_READONLY|PM_HIDEVAL)) {
zwarnnam(name, "no other attributes allowed with -n");
return 1;
}
diff --git a/Test/V10private.ztst b/Test/V10private.ztst
index b191afcb7..b876f548d 100644
--- a/Test/V10private.ztst
+++ b/Test/V10private.ztst
@@ -377,6 +377,13 @@ F:Should we allow "public" namerefs to private parameters?
*?*no such variable: ptr1
*?*no such variable: ptr2
+ () {
+ private x=1
+ unset x
+ x=2
+ }
+0:regression test for unset private
+
%clean
rm -r private.TMP
next prev parent reply other threads:[~2023-09-03 18:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-03 12:06 jsks
2023-09-03 18:02 ` Bart Schaefer [this message]
2023-09-03 18:12 ` Bart Schaefer
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=7a-7eDoRuO+d55g_b=9PMcHoMWpOX6RkoWPMf-g+O74HQ@mail.gmail.com' \
--to=schaefer@brasslantern.com \
--cc=js.shirin@gmail.com \
--cc=zsh-users@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).