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

Reply via email to