Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: Fix nameref errors exposed by Philippe's tests



It's meant for this case:

function use_ref() {
  local -nu from_caller=$1
  local my_var=deeper
  print $from_caller
 […]

This also works without -u. I guess you meant to switch the first two lines of "use_ref". And yes, I understand that the aim of -u is to provide a foolproof wait to refer to enclosing variables.  With just -n there is always the risk that a local variable will inadvertently be referred to if local variables are declared before the named reference is initialized.
 
No, the one being referenced.

local s # declared in h
rs=s # assigned in i

$s is from scope h but is visible in scope i
$rs looks one scope above the visible $s, finds the $s from g

If I follow this logic, then
- with value 0, $s is from scope f but is visible in g. $rs looks one scope above the visible $s, finds the $s from e but the test outputs f, (same for value 1)
- with value 3, $s is from scope g but is visible in h. $rs looks one scope above the visible $s, finds the $s from f but the test outputs g,
- with value 6, $s is from scope i and is visible in i. $rs looks one scope above the visible $s, finds the $s from h but the test outputs g.
- with value 7, $s is from scope i but is visible in j. $rs looks one scope above the visible $s, finds the $s from h but the test outputs g,

The logic "one level above the current scope" correctly explains the current results for values 0 to 4, 11 and 12 but not for values 5 to 10.

Deliberately propagating an uninitialized -u reference from some
higher scope was never really discussed and I'm not sure what the
real-world use-case is, but it may not be too hard to fix.

Even if we don't yet know of any use-case, there should be a clear specification/understanding of what -u does. At the moment that seems to only exist for cases where the reference is initialized in the same scope as where it's defined.

Philippe


On Tue, May 6, 2025 at 12:09 AM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
On Mon, May 5, 2025 at 3:59 PM Philippe Altherr
<philippe.altherr@xxxxxxxxx> wrote:
>>
>> Hm.  It's not looking one level above the current scope, it's looking
>> one level above the parameter currently in scope.
>
> Which parameter? The one being initialized?

No, the one being referenced.

local s # declared in h
rs=s # assigned in i

$s is from scope h but is visible in scope i
$rs looks one scope above the visible $s, finds the $s from g

I can look at this separately but I'm not sure how important it is,
because the intention of -u is to "protect" locals declared in the
current scope; that is, the intention for -u is to always declare both
the named reference and the locals in the same scope.  It's meant for
this case:

function use_ref() {
  local -nu from_caller=$1
  local my_var=deeper
  print $from_caller
}
function the_caller() {
  local my_var=shallower
  use_ref my_var
}
the_caller
(output is "shallower" not "deeper")

Deliberately propagating an uninitialized -u reference from some
higher scope was never really discussed and I'm not sure what the
real-world use-case is, but it may not be too hard to fix.


Messages sorted by: Reverse Date, Date, Thread, Author