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

Re: Up-scope named references, vs. ksh



Lost track of this for a bit ..

On Wed, Feb 21, 2024 at 12:12 PM Stephane Chazelas
<stephane@xxxxxxxxxxxx> wrote:
>
> Like:
> - if var is found (declared) in the current scope, record that
>   it's that of that scope that it is to get the value of or set
>   or unset (and reset again thereafter)
> - if not, repeat for parent scope
> - if not found at all, record that it's to be at the global
>   scope.

That's where this whole discussion started:  It's not good enough to
"record that it's to be global" because if a local of the same name is
later declared, there is no way to insert a new global "above" that,
it's akin to attempting to allocate new space in your caller's stack
frame in C (except there's one stack for each parameter name).  The
workaround in shell code is to start with "typeset -g a" (using your
example code) to initialize the top stack frame.  The workaround in
underlying C code would be to have "typeset -n r1=a" (again your
example) implicitly create the global $a as early as possible.

> f() { typeset a; unset a; g; echo "$a"; }
> g() { h; }
> h() {
>   typeset b=x
>   typeset -n r1=a r2=b r3=c
>   typeset a=foo c=bar
>   r1=x r2=y r3=z
>   unset r{1..3}
>   r1=x r2=y r3=z
> }
> f
>
> r1=x sets the $a of f, r2=y sets the $b of h, and r3=z sets a
> global $c both times.

It works that way for "the $a of f" and "the $b of h", but r3 assigns
"the $c of h" both times.  Change that to:

h() {
  typeset b=x
  typeset -n r1=a r2=b r3=c
  typeset a=foo
  r1=x r2=y r3=z
  typeset c=bar
  unset r{1..3}
  r1=x r2=y r3=z
}

And now the first r3=z creates the global $c so the second r3=z
continues to refer to it.




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