On Sun, Mar 10, 2024, at 1:51 PM, Kerin Millar wrote:
> Dynamic scoping can be tremendously confusing. The following examples
> should help to clarify the present state of affairs.
>
> $ x() { local a; y; echo "outer: $a"; }
> $ y() { local a; a=123; echo "inner: $a"; }
> $ x; echo "outermost: $a"
> inner: 123
> outer:
> outermost:
>
> This is likely as you would expect.
>
> $ y() { local -g a; a=123; echo "inner: $a"; }
> $ x; echo "outermost: $a"
> inner: 123
> outer: 123
> outermost:
>
> This may not be. There, the effect of the -g option effectively ends at
> the outermost scope in which the variable, a, was declared. Namely,
> that of the x function.
This doesn't seem to be accurate; the assignment is performed at
the *innermost* declared scope (other than the "local -g" one):
$ x() { local a; y; echo "outer: $a"; }
$ y() { local a; z; echo "inner: $a"; }
$ z() { local -g a; a=123; echo "innermost: $a"; }
$ x; echo "outermost: $a"
innermost: 123
inner: 123
outer:
outermost:
Basically, without an assignment, "local -g" does nothing.
> The manual states that the "-g option forces variables to be created or
> modified at the global scope, even when declare is executed in a shell
> function" and that "it is ignored in all other cases". I would consider
> this wording insufficient for a user to be able to effectively reason
> with the difference between the second case and the other two cases
> presented.
Later it does say
When used in a function, `declare` makes each _name_ local,
as with the `local` command, unless the `-g` option is used.
but that doesn't really make the consequences of -g clear either.
--
vq