Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: All the way up or current scope
- X-seq: zsh-workers 53587
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: Philippe Altherr <philippe.altherr@xxxxxxxxx>
- Cc: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: All the way up or current scope
- Date: Sun, 11 May 2025 16:18:57 -0700
- Archived-at: <https://zsh.org/workers/53587>
- In-reply-to: <CAGdYchuEL6cs=ACG08txwYP+4BJ_gFZp6hFyTq3K+dbbaPfVfA@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <CAGdYchv84+isv2Y5B+WJtfz7cGtX-L7br+ZUgqshZC2Tc1OoOA@mail.gmail.com> <CAH+w=7aZjPT6xr5uEUL_s1PmuRh9hjZKZ=YvCuCJyE6Ye9iurw@mail.gmail.com> <CAGdYchswJc0CrMm2dbhFRgu6F=8wRiWnjNff0FhqYacDH_KJLA@mail.gmail.com> <CAGdYchsS2_QuHWuSWU1661K5Z8JY4k0p_QAYygdPRu8-Dr3jUA@mail.gmail.com> <CAH+w=7amjvo42qqO-b3+4_bcKo4VJodJEzZe9EYih3Mmo8gLUg@mail.gmail.com> <CAGdYchuEL6cs=ACG08txwYP+4BJ_gFZp6hFyTq3K+dbbaPfVfA@mail.gmail.com>
On Sun, May 11, 2025 at 10:32 AM Philippe Altherr
<philippe.altherr@xxxxxxxxx> wrote:
>
> At any point in time, if ref=var, then consider the innermost scope that was already present when ref was initialized to var,
> - if var was locally defined in that scope before ref was initialized, then ref refers to it,
> - otherwise, ref refers to the first (strictly) enclosing var at that scope, if any and otherwise to the outermost var, if any.
This implies maintaining an order dependency on parameter
declarations, or (equivalently?) a per-reference stack of scopes at
which that reference may be resolved. (The parameter table is an
unordered hash.) I think this is putting too much effort into fixing
an undesirable programming paradigm (to wit, declaring a reference
without knowing where it will be initialized).
You should also try what happens with `setopt warn_nested_var`.
> Since the raison d'être of the -u option is to support passing variables by name, I'm getting convinced that -u is a property of the reference. And not only that. I'm now also convinced that the lookup should not be performed relative to the scope of where the reference is initialized but relative to where the reference is defined.
I actually implemented this at one point amid the other fixes for this
thread, but abandoned it because it violated your assertions about how
the nr-test output should appear.
Adopting this would not conflict with any of the previous K01 tests
and would appear to offer a compromise: A reference declared with -u
would automatically have "all the way up" behavior, because locallevel
would provide the order of declaration constraint. I have no
objection to adopting this.
> Lastly, again because -u is intended to get access to a variable in the caller's scope, I think that if no variable is found there, it should default to an invalid reference that expends to the empty string or maybe even better to an error and not default, like currently, to whatever, if anything, is found in the current scope.
That's not how it currently works. A parameter in the current scope
would be found only if the reference were first defined in a nested
scope to name a parameter that also existed in a (shallower) nested
scope, after which both of those nested scopes return.
() {
# scope with no parameters
() {
local -nu upref
local var=at_upref
() {
local var=below_upref
() {
upref=var
print -- $upref
}
print -- $upref
}
print -- $upref
}
}
In any case you're forgetting about assignments.
() {
# scope with no parameters
() {
local -nu upref=$1
upref=create
} notyet
print $notyet
}
There, "notyet" does not yet exist when upref=notyet is initialized;
the subsequent assignment to upref creates the parameter $notyet in
the calling scope.
(This explicitly does NOT work for upref='notyet[subscript]')
> Note btw, that's what ksh does.
Assignment through a nameref declared to a nonexistent parameter
definitely works in ksh, in both static and dynamic scoping:
$ f() {
> nameref upref=$1
> upref=create
> }
$ g() {
> f notyet
> echo $notyet
> }
$ g
create
$ function q {
> nameref upref=$1
> upref=create
> }
$ function p {
> q notnow
> echo $notnow
> }
$ p
create
$
Messages sorted by:
Reverse Date,
Date,
Thread,
Author