* Re: unset private variables
2023-09-03 12:06 unset private variables jsks
@ 2023-09-03 18:02 ` Bart Schaefer
2023-09-03 18:12 ` Bart Schaefer
0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2023-09-03 18:02 UTC (permalink / raw)
To: Joshua Krusell; +Cc: zsh-users
[-- 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
^ permalink raw reply [flat|nested] 3+ messages in thread