Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: unset private variables
- X-seq: zsh-users 29220
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: Joshua Krusell <js.shirin@xxxxxxxxx>
- Cc: zsh-users@xxxxxxx
- Subject: Re: unset private variables
- Date: Sun, 3 Sep 2023 11:02:58 -0700
- Archived-at: <https://zsh.org/users/29220>
- In-reply-to: <CAOCbtnswt_UYR8psp2sMDT=AYZOVJxmdq92P3jBP=dFghaQmLg@mail.gmail.com>
- List-id: <zsh-users.zsh.org>
- References: <CAOCbtnswt_UYR8psp2sMDT=AYZOVJxmdq92P3jBP=dFghaQmLg@mail.gmail.com>
On Sun, Sep 3, 2023 at 5:06 AM jsks <js.shirin@xxxxxxxxx> 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).
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
Messages sorted by:
Reverse Date,
Date,
Thread,
Author