Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: One more named reference scoping thing
- X-seq: zsh-workers 53560
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: One more named reference scoping thing
- Date: Wed, 7 May 2025 16:03:52 -0700
- Archived-at: <https://zsh.org/workers/53560>
- In-reply-to: <CAH+w=7aUt01qOnU6UU6cYu5cpD=_OF2GWgttyFDt1LVCpvbBoA@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <CAH+w=7aUt01qOnU6UU6cYu5cpD=_OF2GWgttyFDt1LVCpvbBoA@mail.gmail.com>
On Tue, May 6, 2025 at 9:01 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
>
> h then prints the state of the reference after the return from i, but
> it's a -u reference so it can't refer to the local in the same scope
> -- instead it climbs up to g.
>
> Here's where things get interesting. The only thing that changes the
> scope of a named reference is either an assignment or exit from a
> scope, and neither of those has happened. h calls k again -- and now
> the referent is no longer in the same scope as the reference, so when
> k prints it, it refers to h again.
>
> The question is, is this OK?
Thinking further about this, I think a better solution is that when a
referent goes out of scope, the reference loses the -u property along
with it, and just becomes a "normal" named reference that moves to
lower levels as the scopes unwind. This in effect makes the "up" a
property of the referent, rather than of the reference: Once a
referent is found, it "sticks" until it goes out of scope, and
thereafter the reference has no special behavior. Proposed patch
below.
The 2nd hunk below doesn't have any actual effect thanks to the way
upscope() is implemented, but matches the semantics more accurately.
Eric, after this thread concludes I'm going to make a doc update and
then you can proceed to test-3.
diff --git a/Src/params.c b/Src/params.c
index e6fb7fcd0..f37b0cc09 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -5892,8 +5892,11 @@ scanendscope(HashNode hn, UNUSED(int flags))
} else
unsetparam_pm(pm, 0, 0);
} else if ((pm->node.flags & PM_NAMEREF) &&
- pm->base > pm->level && pm->base > locallevel)
+ pm->base >= pm->level && pm->base >= locallevel) {
pm->base = locallevel;
+ if (pm->level < locallevel && (pm->node.flags & PM_UPPER))
+ pm->node.flags &= ~PM_UPPER;
+ }
}
@@ -6404,14 +6407,14 @@ setscope(Param pm)
} else if (!pm->base) {
pm->base = basepm->level;
if ((pm->node.flags & PM_UPPER) &&
- (basepm = upscope(basepm, -(locallevel-1))))
+ (basepm = upscope(basepm, -locallevel)))
pm->base = basepm->level;
}
} else if (pm->base < locallevel && refname &&
(basepm = (Param)getparamnode(realparamtab, refname))) {
pm->base = basepm->level;
if ((pm->node.flags & PM_UPPER) &&
- (basepm = upscope(basepm, -(locallevel-1))))
+ (basepm = upscope(basepm, -locallevel)))
pm->base = basepm->level;
}
if (pm->base > pm->level) {
Messages sorted by:
Reverse Date,
Date,
Thread,
Author